#[cfg(feature = "services-tokio")]
mod tokio {
pub use reqwest::Client;
}
#[cfg(feature = "services-tokio")]
pub use tokio::*;
#[cfg(feature = "services-async")]
mod async_std {
#[cfg(any(
feature = "native-tls-vendored",
feature = "rustls-tls-native-roots",
feature = "rustls-tls-webpki-roots",
feature = "__rustls-tls"
))]
compile_error!("the async std compatible libraries do not support these features");
use std::io;
use isahc::AsyncReadResponseExt;
pub struct Response(isahc::http::Response<isahc::AsyncBody>);
impl Response {
pub fn status(&self) -> http::StatusCode {
http::StatusCode::from_u16(self.0.status().as_u16()).expect("valid status code")
}
pub async fn json<T: serde::de::DeserializeOwned + Unpin>(mut self) -> io::Result<T> {
self.0.json().await.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
pub async fn bytes(mut self) -> io::Result<prost::bytes::Bytes> {
Ok(self.0.bytes().await?.into())
}
}
#[derive(Debug, Clone)]
pub struct Client(isahc::HttpClient);
impl Client {
pub fn new() -> Self {
Self(isahc::HttpClient::new().unwrap())
}
pub fn post(&self, url: url::Url) -> RequestBuilder {
RequestBuilder {
body: Vec::new(),
builder: isahc::http::Request::post(url.as_str()),
client: self.0.clone(),
}
}
}
pub struct RequestBuilder {
builder: isahc::http::request::Builder,
body: Vec<u8>,
client: isahc::HttpClient,
}
impl RequestBuilder {
pub fn headers(mut self, headers: http::HeaderMap) -> Self {
let dst = self.builder.headers_mut().unwrap();
let mut last_name: Option<isahc::http::HeaderName> = None;
for (key, value) in headers {
let name = match key {
Some(key) => {
let name = isahc::http::HeaderName::from_bytes(key.as_str().as_bytes())
.expect("valid header name");
last_name = Some(name.clone());
name
}
None => last_name.clone().expect("HeaderMap yielded a value before any key"),
};
let value = isahc::http::HeaderValue::from_bytes(value.as_bytes())
.expect("valid header value");
dst.append(name, value);
}
self
}
pub fn body(mut self, body: Vec<u8>) -> Self {
self.body = body;
self
}
pub fn timeout(mut self, timeout: std::time::Duration) -> Self {
use isahc::config::Configurable;
self.builder = self.builder.timeout(timeout);
self
}
pub async fn send(self) -> io::Result<Response> {
let request = self.builder.body(self.body).unwrap();
let response = self.client.send_async(request).await?;
Ok(Response(response))
}
}
}
#[cfg(feature = "services-async")]
pub use async_std::*;