pub mod auth;
pub mod service;
pub use reqwest::Client as HttpClient;
use reqwest::{self, header};
use thiserror::Error;
#[derive(Debug)]
pub struct HttpClientFactory {
user_agent: String,
}
impl HttpClientFactory {
pub fn new(pkg_name: impl Into<String>, pkg_version: impl Into<String>) -> Self {
let user_agent = format!("{} v{}", pkg_name.into(), pkg_version.into());
HttpClientFactory::with_user_agent(user_agent)
}
pub fn with_user_agent(user_agent: impl Into<String>) -> Self {
Self {
user_agent: user_agent.into(),
}
}
pub fn create(&self) -> HttpClient {
reqwest::ClientBuilder::new()
.user_agent(self.user_agent())
.build()
.expect("could not create a new HTTP client")
}
pub fn user_agent(&self) -> &str {
&self.user_agent
}
}
pub type HttpResult<T> = Result<T, HttpError>;
#[derive(Debug, Error)]
pub enum HttpError {
#[error("Error while making or processing an HTTP request: {0}")]
Request(#[from] reqwest::Error),
#[error("Error serializing POST body: {0}")]
Serialization(#[from] serde_json::Error),
#[error("Request returned HTTP {0}")]
Http(reqwest::StatusCode),
#[error("Missing Content-Type header")]
MissingContentType,
#[error("Invalid Content-Type header value: {0}")]
InvalidContentType(#[from] header::ToStrError),
#[error("Unexpected content type: {0}")]
UnexpectedContentType(String),
}
pub mod prelude {
pub use crate::auth::Auth;
pub use crate::service::{HttpGet, HttpPost, HttpService};
pub use crate::{HttpClient, HttpClientFactory, HttpError, HttpResult};
pub use reqwest::IntoUrl;
}
#[cfg(test)]
mod tests {
use crate::HttpClientFactory;
use regex::Regex;
impl Default for HttpClientFactory {
fn default() -> Self {
let user_agent = format!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
Self { user_agent }
}
}
#[test]
fn it_returns_user_agent_with_version_number() {
let factory = HttpClientFactory::default();
let user_agent = factory.user_agent();
let version_re = Regex::new(r"^[a-z]+ v\d+\.\d+\.\d+(-(alpha|beta)(\.\d+)?)?$").unwrap();
assert!(
version_re.is_match(&user_agent),
"{} does not match {}",
user_agent,
version_re,
);
}
}