use http_body_util::Full;
use hyper::body::Bytes;
use hyper_util::client::legacy::Client as HyperClient;
use hyperlocal::{UnixClientExt, UnixConnector};
use std::path::Path;
use crate::{Error, Method, Request, RequestBuilder, Response, UnixUrl};
#[derive(Debug, Clone)]
pub struct Client {
inner: HyperClient<UnixConnector, Full<Bytes>>,
}
impl Client {
pub fn new() -> Self {
Self {
inner: HyperClient::unix(),
}
}
pub fn request<P>(&self, method: Method, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
let req = UnixUrl::new(socket, path)
.map(|url| Request::new(method, url))
.map_err(Error::from);
RequestBuilder::new(self.clone(), req)
}
pub fn get<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::GET, socket, path)
}
pub fn post<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::POST, socket, path)
}
pub fn put<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::PUT, socket, path)
}
pub fn patch<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::PATCH, socket, path)
}
pub fn delete<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::DELETE, socket, path)
}
pub fn head<P>(&self, socket: P, path: &str) -> RequestBuilder
where
P: AsRef<Path>,
{
self.request(Method::HEAD, socket, path)
}
pub async fn execute(&self, request: Request) -> Result<Response, Error> {
let (method, url, headers, body, version, extensions) = request.pieces();
let body = match body {
Some(body) => Full::new(body.bytes().clone()),
None => Full::new(Bytes::new()),
};
let mut builder = http::Request::builder()
.method(method)
.uri(url.clone())
.version(version);
if let Some(builder_headers) = builder.headers_mut() {
builder_headers.extend(headers);
}
if let Some(builder_extensions) = builder.extensions_mut() {
builder_extensions.extend(extensions);
}
let req = builder.body(body)?;
let resp = self.inner.request(req).await?;
Ok(Response::new(resp, url))
}
}
impl Default for Client {
fn default() -> Self {
Self::new()
}
}