use core::fmt;
use std::time::Duration;
use reqwest::header::HeaderValue;
pub const MAX_TIMEOUT_SECONDS: u64 = 300;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TimeoutError {
Zero,
TooLong,
ExceedsTotal,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RequestTimeouts {
total: Duration,
connect: Duration,
}
impl RequestTimeouts {
pub fn new(total: Duration, connect: Duration) -> Result<Self, TimeoutError> {
if total.is_zero() || connect.is_zero() {
return Err(TimeoutError::Zero);
}
let maximum = Duration::from_secs(MAX_TIMEOUT_SECONDS);
if total > maximum || connect > maximum {
return Err(TimeoutError::TooLong);
}
if connect > total {
return Err(TimeoutError::ExceedsTotal);
}
Ok(Self { total, connect })
}
pub(crate) const fn total(self) -> Duration {
self.total
}
pub(crate) const fn connect(self) -> Duration {
self.connect
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UserAgentError {
Empty,
TooLong,
Invalid,
}
#[derive(Clone)]
pub struct UserAgent {
pub(crate) value: HeaderValue,
}
impl UserAgent {
pub fn new(value: &str) -> Result<Self, UserAgentError> {
if value.is_empty() {
return Err(UserAgentError::Empty);
}
if value.len() > 256 {
return Err(UserAgentError::TooLong);
}
let value = HeaderValue::from_str(value).map_err(|_| UserAgentError::Invalid)?;
Ok(Self { value })
}
}
impl fmt::Debug for UserAgent {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("UserAgent([validated])")
}
}