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}