hypixel-sdk 0.2.1

Async client for the Hypixel Public API with typed models and SkyBlock helpers
Documentation
use std::sync::{Arc, RwLock};
use std::time::Duration;

use reqwest::header::HeaderMap;

/// A snapshot of the rate-limit state reported by the API on the last response.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct RateLimit {
    /// Maximum number of requests permitted in the current window.
    pub limit: Option<u32>,
    /// Requests remaining in the current window.
    pub remaining: Option<u32>,
    /// Seconds until the current window resets.
    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"),
        }
    }

    /// Duration until the current window resets, if known.
    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()
    }
}