Skip to main content

rate_limits/headers/
types.rs

1use crate::convert;
2use crate::error::Result;
3use crate::reset_time::ResetTimeKind;
4use time::Duration;
5
6/// Known vendors of rate limit headers
7///
8/// Vendors use different rate limit header formats,
9/// which define how to parse them.
10#[derive(Copy, Clone, Debug, PartialEq)]
11pub enum Vendor {
12    /// Rate limit headers as defined in the `polli-ratelimit-headers-00` draft
13    PolliDraft,
14    /// Akamai rate limit headers
15    Akamai,
16    /// Github API rate limit headers
17    Github,
18    /// Gitlab rate limit headers
19    Gitlab,
20    /// Linear rate limit headers (GraphQL)
21    Linear,
22    /// OpenAI rate limit headers
23    OpenAI,
24    /// Reddit rate limit headers
25    Reddit,
26    /// Twilio rate limit headers
27    Twilio,
28    /// Twitter API rate limit headers
29    Twitter,
30    /// Vimeo rate limit headers
31    Vimeo,
32}
33
34/// A variant defines all relevant fields for parsing headers from a given vendor
35#[derive(Clone, Debug, PartialEq)]
36pub(crate) struct RateLimitVariant {
37    /// Vendor of the rate limit headers (e.g. Github, Twitter, etc.)
38    pub(crate) vendor: Vendor,
39    /// Duration of the rate limit interval
40    pub(crate) duration: Option<Duration>,
41    /// Header name for the maximum number of requests
42    pub(crate) limit_header: Option<String>,
43    /// Header name for the number of used requests
44    pub(crate) used_header: Option<String>,
45    /// Header name for the number of remaining requests
46    pub(crate) remaining_header: String,
47    /// Header name for the reset time
48    pub(crate) reset_header: String,
49    /// Kind of reset time
50    pub(crate) reset_kind: ResetTimeKind,
51}
52
53impl RateLimitVariant {
54    /// Create a new rate limit variant
55    #[must_use]
56    pub(crate) const fn new(
57        vendor: Vendor,
58        duration: Option<Duration>,
59        limit_header: Option<String>,
60        used_header: Option<String>,
61        remaining_header: String,
62        reset_header: String,
63        reset_kind: ResetTimeKind,
64    ) -> Self {
65        Self {
66            vendor,
67            duration,
68            limit_header,
69            used_header,
70            remaining_header,
71            reset_header,
72            reset_kind,
73        }
74    }
75}
76
77/// A rate limit header
78#[derive(Clone, Copy, Debug, PartialEq)]
79pub(crate) struct Limit {
80    /// Maximum number of requests for the given interval
81    pub(crate) count: usize,
82}
83
84impl Limit {
85    /// Create a new limit header
86    ///
87    /// # Errors
88    ///
89    /// This function returns an error if the header value cannot be parsed
90    pub(crate) fn new<T: AsRef<str>>(value: T) -> Result<Self> {
91        Ok(Self {
92            count: convert::to_usize(value.as_ref())?,
93        })
94    }
95}
96
97impl From<usize> for Limit {
98    fn from(count: usize) -> Self {
99        Self { count }
100    }
101}
102
103/// A rate limit header for the number of used requests
104#[derive(Clone, Copy, Debug, PartialEq)]
105pub(crate) struct Used {
106    /// Number of used requests for the given interval
107    pub(crate) count: usize,
108}
109
110impl Used {
111    pub(crate) fn new(value: &str) -> Result<Self> {
112        Ok(Self {
113            count: convert::to_usize(value)?,
114        })
115    }
116}
117
118/// A rate limit header for the number of remaining requests
119#[derive(Clone, Copy, Debug, PartialEq)]
120pub(crate) struct Remaining {
121    /// Number of remaining requests for the given interval
122    pub(crate) count: usize,
123}
124
125impl Remaining {
126    /// Create a new remaining header
127    ///
128    /// # Errors
129    ///
130    /// This function returns an error if the header value cannot be parsed
131    pub(crate) fn new(value: &str) -> Result<Self> {
132        Ok(Self {
133            count: convert::to_usize(value)?,
134        })
135    }
136}