use std::ops::{Deref, DerefMut};
use crate::result::InternalResult;
pub use http::request::Builder as HttpBuilder;
pub use http::request::Parts;
pub use http::HeaderName;
pub use http::HeaderValue;
pub use http::Method;
pub use http::Request as HttpRequest;
pub use http::Uri;
#[derive(Default)]
pub struct Request<T>(HttpRequest<T>);
impl<T> Deref for Request<T> {
type Target = http::Request<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Request<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Request<()> {
#[allow(dead_code)]
pub(crate) fn builder() -> Builder {
Builder {
builder: HttpBuilder::new(),
}
}
}
impl<T> Request<T> {
pub fn new(value: T) -> Self {
Self(HttpRequest::new(value))
}
#[inline]
pub fn from_parts(parts: Parts, body: T) -> Request<T> {
Request(HttpRequest::from_parts(parts, body))
}
pub(crate) fn and_then<BodyType>(
self,
callback: impl FnOnce(T) -> InternalResult<BodyType>,
) -> InternalResult<Request<BodyType>> {
let (parts, body) = self.0.into_parts();
callback(body).map(|body| Request(HttpRequest::from_parts(parts, body)))
}
pub fn into_inner(self) -> HttpRequest<T> {
self.0
}
#[inline]
pub fn into_body(self) -> T {
self.0.into_body()
}
#[inline]
pub fn into_parts(self) -> (Parts, T) {
self.0.into_parts()
}
#[inline]
pub fn map<F, U>(self, f: F) -> Request<U>
where
F: FnOnce(T) -> U,
{
Request(self.0.map(f))
}
}
pub(crate) struct Builder {
pub builder: HttpBuilder,
}
#[allow(dead_code)]
impl Builder {
pub(crate) fn uri<T>(self, uri: T) -> Self
where
Uri: TryFrom<T>,
<Uri as TryFrom<T>>::Error: Into<http::Error>,
{
Self {
builder: self.builder.uri(uri),
}
}
pub(crate) fn body<T>(self, body: T) -> Request<T> {
Request(
self.builder
.body(body)
.unwrap(),
)
}
pub fn method(self, method: Method) -> Self {
Self {
builder: self.builder.method(method),
}
}
pub fn header<K, V>(self, key: K, value: V) -> Self
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
{
Self {
builder: self
.builder
.header(key, value),
}
}
}
impl<T> From<Request<T>> for http::Request<T> {
fn from(value: Request<T>) -> Self {
value.0
}
}
impl<T> From<http::Request<T>> for Request<T> {
fn from(value: http::Request<T>) -> Self {
Request(value)
}
}
impl From<Request<String>> for InternalResult<Request<String>> {
fn from(val: Request<String>) -> Self {
Ok(val)
}
}