use crate::{imp, Body, Error, HeaderName, HeaderValue, Response};
use serde::Serialize;
use std::convert::TryInto;
pub struct Request(pub(crate) imp::Req);
impl Request {
pub fn get(uri: &str) -> Request {
Request(imp::Req::get(uri))
}
pub fn post(uri: &str) -> Request {
Request(imp::Req::post(uri))
}
pub fn put(uri: &str) -> Request {
Request(imp::Req::put(uri))
}
pub fn delete(uri: &str) -> Request {
Request(imp::Req::delete(uri))
}
pub fn head(uri: &str) -> Request {
Request(imp::Req::head(uri))
}
pub fn options(uri: &str) -> Request {
Request(imp::Req::options(uri))
}
pub fn new(meth: &str, uri: &str) -> Result<Request, Error> {
imp::Req::new(meth, uri).map(Request)
}
pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> Result<Self, Error> {
self.0.json(json)?;
Ok(self)
}
pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> Result<Self, Error> {
self.0.form(form)?;
Ok(self)
}
pub fn query<T: Serialize + ?Sized>(mut self, query: &T) -> Result<Self, Error> {
self.0.query(query)?;
Ok(self)
}
pub fn body(mut self, body: impl Into<Body>) -> Result<Self, Error> {
self.0.body(body.into())?;
Ok(self)
}
pub fn set_header<N, V, E1, E2>(mut self, name: N, value: V) -> Result<Self, Error>
where
N: TryInto<HeaderName, Error = E1>,
V: TryInto<HeaderValue, Error = E2>,
Error: From<E1>,
Error: From<E2>,
{
let val: HeaderValue = value.try_into()?;
let name: HeaderName = name.try_into()?;
self.0.set_header(name.into(), val.into())?;
Ok(self)
}
pub fn add_header<N, V, E1, E2>(mut self, name: N, value: V) -> Result<Self, Error>
where
N: TryInto<HeaderName, Error = E1>,
V: TryInto<HeaderValue, Error = E2>,
Error: From<E1>,
Error: From<E2>,
{
let val: HeaderValue = value.try_into()?;
let name: HeaderName = name.try_into()?;
self.0.add_header(name.into(), val.into())?;
Ok(self)
}
pub async fn exec(self) -> Result<Response, Error> {
let r = self.0.send_request().await.map(Response)?;
if r.status_code() > 299 && r.status_code() < 399 {
if let Some(loc) = r.header("Location").and_then(|l| l.try_into().ok()) {
let _l: String = loc;
}
}
Ok(r)
}
}
impl std::fmt::Debug for Request {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.0, f)
}
}