use reqwest::{Client, RequestBuilder, Response};
use serde::de::DeserializeOwned;
use std::time::Duration;
use crate::error::{Error, Result};
pub const USER_AGENT: &str = "Mozilla/5.0 (compatible; SoopClient/3.0)";
pub const DEFAULT_HTTP_TIMEOUT: Duration = Duration::from_secs(15);
pub fn with_user_agent(request: RequestBuilder) -> RequestBuilder {
request.header("User-Agent", USER_AGENT)
}
pub fn with_form_headers(request: RequestBuilder) -> RequestBuilder {
with_user_agent(request).header("Content-Type", "application/x-www-form-urlencoded")
}
pub async fn send(request: RequestBuilder) -> Result<Response> {
let response = request.send().await.map_err(Error::Transport)?;
ensure_success(response)
}
pub async fn send_json<T>(request: RequestBuilder) -> Result<T>
where
T: DeserializeOwned,
{
let response = send(request).await?;
response
.json::<T>()
.await
.map_err(|e| Error::Decode(e.to_string()))
}
pub async fn send_text(request: RequestBuilder) -> Result<String> {
let response = send(request).await?;
response
.text()
.await
.map_err(|e| Error::Decode(e.to_string()))
}
pub fn ensure_success(response: Response) -> Result<Response> {
if response.status().is_success() {
return Ok(response);
}
let status = response.status();
let url = response.url().to_string();
Err(Error::HttpStatus { status, url })
}
pub fn default_client() -> Client {
Client::builder()
.timeout(DEFAULT_HTTP_TIMEOUT)
.build()
.unwrap_or_else(|_| Client::new())
}