use std::ops::Deref;
use crate::{
Body, Method, Request, RequestHeader, Version,
header::HeaderField,
request::RequestBuilder,
url::{IntoUrl, Url, UrlParseError},
};
pub struct OutgoingRequestBuilder {
inner: RequestBuilder,
url: Url,
}
impl OutgoingRequestBuilder {
#[inline(never)]
fn new(version: Version, method: Method, url: Url) -> Self {
let path = String::from(url.path_with_query());
Self {
inner: Request::builder(version, method, path.into()),
url,
}
}
#[inline]
pub fn set_version(mut self, version: Version) -> Self {
self.inner = self.inner.set_version(version);
self
}
#[inline]
pub fn set_method(mut self, method: Method) -> Self {
self.inner = self.inner.set_method(method);
self
}
pub fn set_url(mut self, url: Url) -> Self {
let path = String::from(url.path_with_query());
self.inner = self.inner.set_path(path.into());
self.url = url;
self
}
pub fn set_header_field<T>(mut self, field: T) -> Self
where
T: Into<HeaderField>,
{
self.inner = self.inner.set_header_field(field);
self
}
pub fn add_header_field<T>(mut self, field: T) -> Self
where
T: Into<HeaderField>,
{
self.inner = self.inner.add_header_field(field);
self
}
pub fn remove_header_field<N>(mut self, name: &N) -> Self
where
N: AsRef<[u8]> + ?Sized,
{
self.inner = self.inner.remove_header_fields(name);
self
}
pub fn body<B>(self, body: B) -> OutgoingRequest<B> {
let request = self.inner.body(body);
OutgoingRequest {
inner: request,
url: self.url,
}
}
}
pub struct OutgoingRequest<B = Body> {
inner: Request<B>,
url: Url,
}
impl OutgoingRequest<()> {
pub fn builder<U>(method: Method, url: U) -> Result<OutgoingRequestBuilder, UrlParseError>
where
U: IntoUrl,
{
let url = url.into_url()?;
Ok(OutgoingRequestBuilder::new(Version::Version11, method, url))
}
pub fn get<U>(url: U) -> Result<OutgoingRequestBuilder, UrlParseError>
where
U: IntoUrl,
{
Self::builder(Method::Get, url)
}
pub fn put<U>(url: U) -> Result<OutgoingRequestBuilder, UrlParseError>
where
U: IntoUrl,
{
Self::builder(Method::Put, url)
}
pub fn post<U>(url: U) -> Result<OutgoingRequestBuilder, UrlParseError>
where
U: IntoUrl,
{
Self::builder(Method::Post, url)
}
pub fn delete<U>(url: U) -> Result<OutgoingRequestBuilder, UrlParseError>
where
U: IntoUrl,
{
Self::builder(Method::Delete, url)
}
}
impl<B> OutgoingRequest<B> {
#[inline]
pub fn url(&self) -> &Url {
&self.url
}
#[inline]
pub fn deconstruct(self) -> (Url, RequestHeader, B) {
let (header, body) = self.inner.deconstruct();
(self.url, header, body)
}
pub fn into_builder(self) -> (OutgoingRequestBuilder, B) {
let (header, body) = self.inner.deconstruct();
let builder = OutgoingRequestBuilder {
inner: header.into(),
url: self.url,
};
(builder, body)
}
}
impl<B> Deref for OutgoingRequest<B> {
type Target = Request<B>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}