use crate::error::{ErrorKind, Result, ResultExt};
use crate::headers::{AsHeaders, Headers};
use crate::SeekableStream;
use bytes::Bytes;
use http::{Method, Uri};
use std::fmt::Debug;
use std::str::FromStr;
#[derive(Debug, Clone)]
pub enum Body {
Bytes(bytes::Bytes),
SeekableStream(Box<dyn SeekableStream>),
}
impl<B> From<B> for Body
where
B: Into<Bytes>,
{
fn from(bytes: B) -> Self {
Self::Bytes(bytes.into())
}
}
impl From<Box<dyn SeekableStream>> for Body {
fn from(seekable_stream: Box<dyn SeekableStream>) -> Self {
Self::SeekableStream(seekable_stream)
}
}
#[derive(Debug, Clone)]
pub struct Request {
pub(crate) uri: Uri,
pub(crate) method: Method,
pub(crate) headers: Headers,
pub(crate) body: Body,
}
impl Request {
pub fn new(uri: Uri, method: Method) -> Self {
Self {
uri,
method,
headers: Headers::new(),
body: Body::Bytes(bytes::Bytes::new()),
}
}
pub fn uri(&self) -> &Uri {
&self.uri
}
pub fn method(&self) -> Method {
self.method.clone()
}
pub fn insert_headers<T: AsHeaders>(&mut self, headers: &T) {
for (name, value) in headers.as_headers() {
self.headers_mut().insert(name, value)
}
}
pub fn headers(&self) -> &Headers {
&self.headers
}
pub fn headers_mut(&mut self) -> &mut Headers {
&mut self.headers
}
pub fn body(&self) -> &Body {
&self.body
}
pub fn set_body(&mut self, body: impl Into<Body>) {
self.body = body.into();
}
pub fn parse_uri(uri: &str) -> Result<Uri> {
Uri::from_str(uri).map_kind(ErrorKind::DataConversion)
}
}
impl From<http::Request<bytes::Bytes>> for Request {
fn from(request: http::Request<bytes::Bytes>) -> Self {
let (parts, body) = request.into_parts();
Self {
uri: parts.uri,
method: parts.method,
headers: parts.headers.into(),
body: Body::Bytes(body),
}
}
}