twitch_api_rs/
values.rs

1//! Wrappers for basic owned types that indicate their usage
2#![allow(missing_docs)]
3
4// {{{ macros
5#[macro_export]
6#[doc(hidden)]
7macro_rules! field_wrapper_name {
8    ($($type:ty => $field:expr),+) => {
9        $(
10            impl FieldValue for $type {
11                fn field_name() -> &'static str {
12                    $field
13                }
14            }
15        )*
16    };
17}
18
19#[macro_export]
20#[doc(hidden)]
21macro_rules! quick_deref_into {
22    ($(($type:ty, $inner:ty)),+) => {
23        $(
24            impl std::ops::Deref for $type {
25                type Target = $inner;
26                fn deref(&self) -> &$inner {
27                    &self.0
28                }
29            }
30
31            impl std::ops::DerefMut for $type {
32                fn deref_mut(&mut self) -> &mut $inner {
33                    &mut self.0
34                }
35            }
36
37            impl $type {
38                /// Take the inner value of this object
39                pub fn into_inner(self) -> $inner {
40                    self.0
41                }
42            }
43
44        )*
45    }
46}
47
48#[macro_export]
49#[doc(hidden)]
50macro_rules! from_inner {
51    ($(($type:ty, $inner:ty)),+) => {
52        $(
53            impl<T: Into<$inner>> From<T> for $type {
54                fn from(f: T) -> Self {
55                    Self(f.into())
56                }
57            }
58        )*
59    }
60}
61
62// }}}
63
64use serde::{Deserialize, Serialize};
65
66/// Values for broadcaster objects and requests
67pub mod broadcasters {
68    use super::*;
69
70    #[repr(transparent)]
71    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
72    #[serde(transparent)]
73    /// The id number of a broadcaster object
74    pub struct BroadcasterId(String);
75
76    use super::users::UserId;
77    impl From<UserId> for BroadcasterId {
78        fn from(u: UserId) -> Self {
79            Self(u.into_inner())
80        }
81    }
82
83    #[repr(transparent)]
84    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85    #[serde(transparent)]
86    /// The display name of a channel object
87    pub struct BroadcasterName(String);
88
89    #[repr(transparent)]
90    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
91    #[serde(transparent)]
92    /// The language of a broadcaster object
93    pub struct BroadcasterLanguage(ISOLanguage);
94
95    #[repr(transparent)]
96    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
97    #[serde(transparent)]
98    /// The type of broadcaster: Affiliate, Partner, or empty
99    pub struct BroadcasterType(String);
100
101    #[repr(transparent)]
102    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
103    #[serde(transparent)]
104    /// The total number of views on this broadcasters channel
105    pub struct BroadcasterViews(u64);
106
107    field_wrapper_name![
108        BroadcasterId => "broadcaster_id",
109        BroadcasterName => "broadcaster_name",
110        BroadcasterLanguage => "broadcaster_language",
111        BroadcasterType => "broadcaster_type",
112        BroadcasterViews => "view_count"
113    ];
114
115    quick_deref_into![
116        (BroadcasterId, String),
117        (BroadcasterName, String),
118        (BroadcasterLanguage, ISOLanguage),
119        (BroadcasterType, String),
120        (BroadcasterViews, u64)
121    ];
122
123    from_inner![
124        (BroadcasterId, String),
125        (BroadcasterName, String),
126        (BroadcasterLanguage, ISOLanguage),
127        (BroadcasterType, String),
128        (BroadcasterViews, u64)
129    ];
130}
131
132/// Values for game objects and requests
133pub mod games {
134    use super::*;
135
136    #[repr(transparent)]
137    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
138    #[serde(transparent)]
139    pub struct GameName(String);
140
141    #[repr(transparent)]
142    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
143    #[serde(transparent)]
144    /// The ID number of a game on twitch
145    pub struct GameId(String);
146
147    field_wrapper_name![
148        GameName => "game_name",
149        GameId => "game_id"
150    ];
151
152    quick_deref_into![(GameName, String), (GameId, String)];
153    from_inner![(GameName, String), (GameId, String)];
154}
155
156/// Values for extension objects and requests
157pub mod extensions {
158    use super::*;
159
160    #[repr(transparent)]
161    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162    #[serde(transparent)]
163    /// The id assined to an extension when it was created
164    pub struct ExtensionId(String);
165
166    field_wrapper_name![
167        ExtensionId => "extension_id"
168    ];
169
170    quick_deref_into![(ExtensionId, String)];
171    from_inner![(ExtensionId, String)];
172}
173
174/// Values for clip objects and requests
175pub mod clips {
176    use super::*;
177
178    #[repr(transparent)]
179    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
180    #[serde(transparent)]
181    pub struct ClipId(String);
182
183    #[repr(transparent)]
184    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
185    #[serde(transparent)]
186    pub struct ClipTitle(String);
187
188    #[repr(transparent)]
189    #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
190    #[serde(transparent)]
191    pub struct ViewCount(u32);
192
193    field_wrapper_name![
194        ClipId => "id",
195        ClipTitle => "title",
196        ViewCount => "view_count"
197    ];
198
199    quick_deref_into![(ClipId, String), (ClipTitle, String), (ViewCount, u32)];
200
201    from_inner![(ClipId, String), (ClipTitle, String), (ViewCount, u32)];
202}
203
204/// Values for user objects and requests
205pub mod users {
206    use super::*;
207
208    #[repr(transparent)]
209    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
210    #[serde(transparent)]
211    pub struct UserId(String);
212
213    use super::broadcasters::BroadcasterId;
214    impl From<BroadcasterId> for UserId {
215        fn from(b: BroadcasterId) -> Self {
216            Self(b.into_inner())
217        }
218    }
219
220    #[repr(transparent)]
221    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
222    #[serde(transparent)]
223    pub struct UserName(String);
224
225    #[repr(transparent)]
226    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
227    #[serde(transparent)]
228    /// the login name for this user
229    pub struct UserLogin(String);
230
231    #[repr(transparent)]
232    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
233    #[serde(transparent)]
234    /// The type of this user: Staff, Admin, Global_Mod, or empty
235    pub struct UserType(String);
236
237    #[repr(transparent)]
238    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
239    #[serde(transparent)]
240    /// The email of the user, generally only returned by a request if the access token
241    /// provided has the [`scope`] 'user:read:email'
242    ///
243    /// [`scope`]: https://dev.twitch.tv/docs/authentication#scopes
244    pub struct UserEmail(String);
245
246    field_wrapper_name![
247        UserId => "id",
248        UserName => "user_name",
249        UserLogin => "login",
250        UserType => "type",
251        UserEmail => "email"
252    ];
253
254    quick_deref_into![
255        (UserId, String),
256        (UserName, String),
257        (UserLogin, String),
258        (UserType, String),
259        (UserEmail, String)
260    ];
261
262    from_inner![
263        (UserId, String),
264        (UserName, String),
265        (UserLogin, String),
266        (UserType, String),
267        (UserEmail, String)
268    ];
269}
270
271pub mod videos {
272    use super::*;
273
274    #[repr(transparent)]
275    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
276    #[serde(transparent)]
277    pub struct VideoId(String);
278
279    #[repr(transparent)]
280    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
281    #[serde(transparent)]
282    pub struct VideoLanguage(ISOLanguage);
283
284    field_wrapper_name![
285        VideoId => "id",
286        VideoLanguage => "language"
287    ];
288
289    quick_deref_into![(VideoId, String), (VideoLanguage, ISOLanguage)];
290    from_inner![(VideoId, String), (VideoLanguage, ISOLanguage)];
291}
292
293#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
294/// A Pagination key for enpoints that may return more than 100 results
295pub struct Pagination {
296    pub cursor: Option<String>,
297}
298
299impl From<String> for Pagination {
300    fn from(inner: String) -> Self {
301        Self {
302            cursor: Some(inner),
303        }
304    }
305}
306
307#[repr(transparent)]
308#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
309#[serde(transparent)]
310/// The max amount returned per page, used in requests like
311/// [`crate::resource::clips::get_clips::GetClipsRequest`]
312pub struct Count(u32);
313
314#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
315/// Represents a time window
316pub struct Period {
317    pub started_at: StartedAt,
318    pub ended_at: EndedAt,
319}
320
321#[repr(transparent)]
322#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
323#[serde(transparent)]
324/// Represents a [`RFC3339`] formatted datetime
325///
326/// [`RFC3339`]: https://datatracker.ietf.org/doc/rfc3339/
327pub struct RFC3339Time(String);
328
329#[repr(transparent)]
330#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
331#[serde(transparent)]
332/// Represents the beginning of a time window
333pub struct StartedAt(RFC3339Time);
334
335#[repr(transparent)]
336#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
337#[serde(transparent)]
338/// Represents the end of a time window
339pub struct EndedAt(RFC3339Time);
340
341#[repr(transparent)]
342#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
343#[serde(transparent)]
344/// Represents a language, either a [`ISO 639-1`] two-letter language code or 'other'
345///
346/// [`ISO 639-1`]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
347pub struct ISOLanguage(String);
348
349#[repr(transparent)]
350#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
351#[serde(transparent)]
352pub struct Url(String);
353
354field_wrapper_name![
355    Pagination => "pagination",
356    Count => "count",
357
358    RFC3339Time => "time",
359    Period => "period",
360    StartedAt => "started_at",
361    EndedAt => "ended_at",
362    ISOLanguage => "language"
363];
364
365quick_deref_into![
366    (RFC3339Time, String),
367    (StartedAt, RFC3339Time),
368    (EndedAt, RFC3339Time),
369    (ISOLanguage, String),
370    (Url, String)
371];
372
373from_inner![
374    (RFC3339Time, String),
375    (StartedAt, RFC3339Time),
376    (EndedAt, RFC3339Time),
377    (ISOLanguage, String),
378    (Url, String)
379];
380
381/// Used to indicated that this type is used a field value
382pub trait FieldValue {
383    /// Get the commonly used name of a field of this type that twitch is expecting
384    fn field_name() -> &'static str;
385}