use std::sync::{Arc, RwLock};
use std::time::Duration;
use reqwest::header::HeaderMap;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct RateLimit {
pub limit: Option<u32>,
pub remaining: Option<u32>,
pub reset: Option<u64>,
}
impl RateLimit {
pub(crate) fn from_headers(headers: &HeaderMap) -> Self {
fn parse<T: std::str::FromStr>(headers: &HeaderMap, name: &str) -> Option<T> {
headers
.get(name)
.and_then(|v| v.to_str().ok())
.and_then(|v| v.trim().parse().ok())
}
RateLimit {
limit: parse(headers, "ratelimit-limit"),
remaining: parse(headers, "ratelimit-remaining"),
reset: parse(headers, "ratelimit-reset"),
}
}
pub fn reset_after(&self) -> Option<Duration> {
self.reset.map(Duration::from_secs)
}
}
#[derive(Debug, Clone, Default)]
pub(crate) struct SharedRateLimit(Arc<RwLock<RateLimit>>);
impl SharedRateLimit {
pub(crate) fn store(&self, value: RateLimit) {
if let Ok(mut guard) = self.0.write() {
*guard = value;
}
}
pub(crate) fn load(&self) -> RateLimit {
self.0.read().map(|g| *g).unwrap_or_default()
}
}