twitch_oauth2/
scopes.rs

1//! Module for all possible scopes in twitch.
2pub mod validator;
3pub use validator::Validator;
4
5use serde_derive::{Deserialize, Serialize};
6use std::borrow::Cow;
7
8macro_rules! scope_impls {
9    (@omit #[deprecated($depr:tt)] $i:ident) => {
10        #[cfg(_internal_never)]
11        Self::$i
12    };
13    (@omit $i:ident) => {
14        Self::$i
15    };
16
17    ($($(#[cfg(($cfg:meta))])* $(#[deprecated($depr:meta)])? $i:ident,scope: $rename:literal, doc: $doc:literal);* $(;)? ) => {
18        #[doc = "Scopes for twitch."]
19        #[doc = ""]
20        #[doc = "<https://dev.twitch.tv/docs/authentication/scopes/>"]
21        #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
22        #[non_exhaustive]
23        #[serde(from = "String")]
24        #[serde(into = "String")]
25        pub enum Scope {
26            $(
27                $(#[cfg($cfg)])*
28                $(#[deprecated($depr)])*
29                #[doc = $doc]
30                #[doc = "\n\n"]
31                #[doc = "`"]
32                #[doc = $rename]
33                #[doc = "`"]
34                #[serde(rename = $rename)] // Is this even needed?
35                $i,
36            )*
37            #[doc = "Other scope that is not implemented."]
38            Other(Cow<'static, str>),
39        }
40
41        impl std::fmt::Display for Scope {
42            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43                #![allow(deprecated)]
44
45                f.write_str(match self {
46                    Scope::Other(s) => &s,
47                    $(
48                        $(#[cfg($cfg)])*
49                        Scope::$i => $rename,
50                    )*
51                })
52            }
53        }
54
55        impl Scope {
56            #[doc = "Get a vec of all defined twitch [Scopes][Scope]."]
57            #[doc = "\n\n"]
58            #[doc = "Please note that this may not work for you, as some auth flows and \"apis\" don't accept all scopes"]
59            pub fn all() -> Vec<Scope> {
60                vec![
61                    $(
62                        scope_impls!(@omit $(#[deprecated($depr)])* $i),
63                    )*
64                ]
65            }
66
67            #[doc = "Get a slice of all defined twitch [Scopes][Scope]."]
68            #[doc = "\n\n"]
69            #[doc = "Please note that this may not work for you, as some auth flows and \"apis\" don't accept all scopes"]
70            pub const fn all_slice() -> &'static [Scope] {
71                &[
72                    $(
73                        scope_impls!(@omit $(#[deprecated($depr)])* $i),
74                    )*
75                ]
76            }
77
78            #[doc = "Get a description for the token"]
79            pub const fn description(&self) -> &'static str {
80                #![allow(deprecated)]
81
82                match self {
83
84                    $(
85                        $(#[cfg($cfg)])*
86                        Self::$i => $doc,
87                    )*
88                    _ => "unknown scope"
89                }
90            }
91
92            #[doc = "Make a scope from a cow string"]
93            pub fn parse<C>(s: C) -> Scope where C: Into<Cow<'static, str>> {
94                #![allow(deprecated)]
95                use std::borrow::Borrow;
96                let s = s.into();
97                match s.borrow() {
98
99                    $(
100                        $(#[cfg($cfg)])*
101                        $rename => {Scope::$i}
102                    )*,
103                    _ => Scope::Other(s)
104                }
105            }
106
107            /// Get the scope as a borrowed string.
108            pub fn as_str(&self) -> &str {
109                #![allow(deprecated)]
110                match self {
111                    $(
112                        $(#[cfg($cfg)])*
113                        Scope::$i => $rename,
114                    )*
115                    Self::Other(c) => c.as_ref()
116                }
117            }
118
119            /// Get the scope as a static string slice.
120            ///
121            /// ## Panics
122            ///
123            /// This function panics if the scope can't be represented as a static string slice
124            pub const fn as_static_str(&self) -> &'static str {
125                #![allow(deprecated)]
126                match self {
127                    $(
128                        $(#[cfg($cfg)])*
129                        Scope::$i => $rename,
130                    )*
131                    Self::Other(Cow::Borrowed(s)) => s,
132                    _ => panic!(),
133                }
134            }
135        }
136        #[test]
137        #[cfg(test)]
138        fn sorted() {
139            let slice = [$(
140                $(#[cfg($cfg)])*
141                $rename,
142            )*];
143            let mut slice_sorted = [$(
144                $(#[cfg($cfg)])*
145                $rename,
146            )*];
147            slice_sorted.sort();
148            for (scope, sorted) in slice.iter().zip(slice_sorted.iter()) {
149                assert_eq!(scope, sorted);
150            }
151            assert_eq!(slice, slice_sorted);
152        }
153    };
154}
155
156scope_impls!(
157    AnalyticsReadExtensions,        scope: "analytics:read:extensions",         doc: "View analytics data for the Twitch Extensions owned by the authenticated account.";
158    AnalyticsReadGames,             scope: "analytics:read:games",              doc: "View analytics data for the games owned by the authenticated account.";
159    BitsRead,                       scope: "bits:read",                         doc: "View Bits information for a channel.";
160    ChannelBot,                     scope: "channel:bot",                       doc: "Allows the client’s bot users access to a channel.";
161    ChannelEditCommercial,          scope: "channel:edit:commercial",           doc: "Run commercials on a channel.";
162    ChannelManageAds,               scope: "channel:manage:ads",                doc: "Manage ads schedule on a channel.";
163    ChannelManageBroadcast,         scope: "channel:manage:broadcast",          doc: "Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags.";
164    ChannelManageExtensions,        scope: "channel:manage:extensions",         doc: "Manage a channel’s Extension configuration, including activating Extensions.";
165    ChannelManageGuestStar,         scope: "channel:manage:guest_star",         doc: "Manage Guest Star for your channel.";
166    ChannelManageModerators,        scope: "channel:manage:moderators",         doc: "Add or remove the moderator role from users in your channel.";
167    ChannelManagePolls,             scope: "channel:manage:polls",              doc: "Manage a channel’s polls.";
168    ChannelManagePredictions,       scope: "channel:manage:predictions",        doc: "Manage of channel’s Channel Points Predictions";
169    ChannelManageRaids,             scope: "channel:manage:raids",              doc: "Manage a channel raiding another channel.";
170    ChannelManageRedemptions,       scope: "channel:manage:redemptions",        doc: "Manage Channel Points custom rewards and their redemptions on a channel.";
171    ChannelManageSchedule,          scope: "channel:manage:schedule",           doc: "Manage a channel’s stream schedule.";
172    ChannelManageVideos,            scope: "channel:manage:videos",             doc: "Manage a channel’s videos, including deleting videos.";
173    ChannelManageVips,              scope: "channel:manage:vips",               doc: "Add or remove the VIP role from users in your channel.";
174    ChannelModerate,                scope: "channel:moderate",                  doc: "Perform moderation actions in a channel. The user requesting the scope must be a moderator in the channel.";
175    ChannelReadAds,                 scope: "channel:read:ads",                  doc: "Read the ads schedule and details on your channel.";
176    ChannelReadCharity,             scope: "channel:read:charity",              doc: "Read charity campaign details and user donations on your channel.";
177    ChannelReadEditors,             scope: "channel:read:editors",              doc: "View a list of users with the editor role for a channel.";
178    ChannelReadGoals,               scope: "channel:read:goals",                doc: "View Creator Goals for a channel.";
179    ChannelReadGuestStar,           scope: "channel:read:guest_star",           doc: "Read Guest Star details for your channel.";
180    ChannelReadHypeTrain,           scope: "channel:read:hype_train",           doc: "View Hype Train information for a channel.";
181    ChannelReadPolls,               scope: "channel:read:polls",                doc: "View a channel’s polls.";
182    ChannelReadPredictions,         scope: "channel:read:predictions",          doc: "View a channel’s Channel Points Predictions.";
183    ChannelReadRedemptions,         scope: "channel:read:redemptions",          doc: "View Channel Points custom rewards and their redemptions on a channel.";
184    ChannelReadStreamKey,           scope: "channel:read:stream_key",           doc: "View an authorized user’s stream key.";
185    ChannelReadSubscriptions,       scope: "channel:read:subscriptions",        doc: "View a list of all subscribers to a channel and check if a user is subscribed to a channel.";
186    ChannelReadVips,                scope: "channel:read:vips",                 doc: "Read the list of VIPs in your channel.";
187    #[deprecated(note = "Use `ChannelReadSubscriptions` (`channel:read:subscriptions`) instead")]
188    ChannelSubscriptions,           scope: "channel_subscriptions",             doc: "Read all subscribers to your channel.";
189    ChatEdit,                       scope: "chat:edit",                         doc: "Send live stream chat and rooms messages.";
190    ChatRead,                       scope: "chat:read",                         doc: "View live stream chat and rooms messages.";
191    ClipsEdit,                      scope: "clips:edit",                        doc: "Manage Clips for a channel.";
192    ModerationRead,                 scope: "moderation:read",                   doc: "View a channel’s moderation data including Moderators, Bans, Timeouts, and Automod settings.";
193    ModeratorManageAnnouncements,   scope: "moderator:manage:announcements",    doc: "Send announcements in channels where you have the moderator role.";
194    ModeratorManageAutoMod,         scope: "moderator:manage:automod",          doc: "Manage messages held for review by AutoMod in channels where you are a moderator.";
195    ModeratorManageAutomodSettings, scope: "moderator:manage:automod_settings", doc: "Manage a broadcaster’s AutoMod settings";
196    ModeratorManageBannedUsers,     scope: "moderator:manage:banned_users",     doc: "Ban and unban users.";
197    ModeratorManageBlockedTerms,    scope: "moderator:manage:blocked_terms",    doc: "Manage a broadcaster’s list of blocked terms.";
198    ModeratorManageChatMessages,    scope: "moderator:manage:chat_messages",    doc: "Delete chat messages in channels where you have the moderator role";
199    ModeratorManageChatSettings,    scope: "moderator:manage:chat_settings",    doc: "View a broadcaster’s chat room settings.";
200    ModeratorManageGuestStar,       scope: "moderator:manage:guest_star",       doc: "Manage Guest Star for channels where you are a Guest Star moderator.";
201    ModeratorManageShieldMode,      scope: "moderator:manage:shield_mode",      doc: "Manage a broadcaster’s Shield Mode status.";
202    ModeratorManageShoutouts,       scope: "moderator:manage:shoutouts",        doc: "Manage a broadcaster’s shoutouts.";
203    ModeratorManageUnbanRequests,   scope: "moderator:manage:unban_requests",   doc: "Manage a broadcaster’s unban requests.";
204    ModeratorManageWarnings,        scope: "moderator:manage:warnings",         doc: "Manage a broadcaster’s chat warnings.";
205    ModeratorReadAutomodSettings,   scope: "moderator:read:automod_settings",   doc: "View a broadcaster’s AutoMod settings.";
206    ModeratorReadBannedUsers,       scope: "moderator:read:banned_users",       doc: "Read the list of bans or unbans in channels where you have the moderator role.";
207    ModeratorReadBlockedTerms,      scope: "moderator:read:blocked_terms",      doc: "View a broadcaster’s list of blocked terms.";
208    ModeratorReadChatMessages,      scope: "moderator:read:chat_messages",      doc: "Read deleted chat messages in channels where you have the moderator role.";
209    ModeratorReadChatSettings,      scope: "moderator:read:chat_settings",      doc: "View a broadcaster’s chat room settings.";
210    ModeratorReadChatters,          scope: "moderator:read:chatters",           doc: "View the chatters in a broadcaster’s chat room.";
211    ModeratorReadFollowers,         scope: "moderator:read:followers",          doc: "Read the followers of a broadcaster.";
212    ModeratorReadGuestStar,         scope: "moderator:read:guest_star",         doc: "Read Guest Star details for channels where you are a Guest Star moderator.";
213    ModeratorReadModerators,        scope: "moderator:read:moderators",         doc: "Read the list of moderators in channels where you have the moderator role.";
214    ModeratorReadShieldMode,        scope: "moderator:read:shield_mode",        doc: "View a broadcaster’s Shield Mode status.";
215    ModeratorReadShoutouts,         scope: "moderator:read:shoutouts",          doc: "View a broadcaster’s shoutouts.";
216    ModeratorReadSuspiciousUsers,   scope: "moderator:read:suspicious_users",   doc: "Read chat messages from suspicious users and see users flagged as suspicious in channels where you have the moderator role.";
217    ModeratorReadUnbanRequests,     scope: "moderator:read:unban_requests",     doc: "View a broadcaster’s unban requests.";
218    ModeratorReadVips,              scope: "moderator:read:vips",               doc: "Read the list of VIPs in channels where you have the moderator role.";
219    ModeratorReadWarnings,          scope: "moderator:read:warnings",           doc: "View a broadcaster’s chat warnings.";
220    UserBot,                        scope: "user:bot",                          doc: "Allows client’s bot to act as this user.";
221    UserEdit,                       scope: "user:edit",                         doc: "Manage a user object.";
222    UserEditBroadcast,              scope: "user:edit:broadcast",               doc: "Edit your channel's broadcast configuration, including extension configuration. (This scope implies user:read:broadcast capability.)";
223    #[deprecated(note = "Not used anymore, see https://discuss.dev.twitch.tv/t/deprecation-of-create-and-delete-follows-api-endpoints/32351")]
224    UserEditFollows,                scope: "user:edit:follows",                 doc: "\\[DEPRECATED\\] Was previously used for “Create User Follows” and “Delete User Follows.";
225    UserManageBlockedUsers,         scope: "user:manage:blocked_users",         doc: "Manage the block list of a user.";
226    UserManageChatColor,            scope: "user:manage:chat_color",            doc: "Update the color used for the user’s name in chat.Update User Chat Color";
227    UserManageWhispers,             scope: "user:manage:whispers",              doc: "Read whispers that you send and receive, and send whispers on your behalf.";
228    UserReadBlockedUsers,           scope: "user:read:blocked_users",           doc: "View the block list of a user.";
229    UserReadBroadcast,              scope: "user:read:broadcast",               doc: "View a user’s broadcasting configuration, including Extension configurations.";
230    UserReadChat,                   scope: "user:read:chat",                    doc: "View live stream chat and room messages.";
231    UserReadEmail,                  scope: "user:read:email",                   doc: "View a user’s email address.";
232    UserReadEmotes,                 scope: "user:read:emotes",                  doc: "View emotes available to a user";
233    UserReadFollows,                scope: "user:read:follows",                 doc: "View the list of channels a user follows.";
234    UserReadModeratedChannels,      scope: "user:read:moderated_channels",      doc: "Read the list of channels you have moderator privileges in.";
235    UserReadSubscriptions,          scope: "user:read:subscriptions",           doc: "View if an authorized user is subscribed to specific channels.";
236    UserReadWhispers,               scope: "user:read:whispers",                doc: "Receive whispers sent to your user.";
237    UserWriteChat,                  scope: "user:write:chat",                   doc: "Send messages in a chat room.";
238    WhispersEdit,                   scope: "whispers:edit",                     doc: "Send whisper messages.";
239    WhispersRead,                   scope: "whispers:read",                     doc: "View your whisper messages.";
240);
241
242impl Scope {
243    /// Get the scope as a [validator](Validator).
244    pub const fn to_validator(self) -> Validator { Validator::scope(self) }
245}
246
247impl std::borrow::Borrow<str> for Scope {
248    fn borrow(&self) -> &str { self.as_str() }
249}
250
251impl From<String> for Scope {
252    fn from(s: String) -> Self { Scope::parse(s) }
253}
254
255impl From<Scope> for String {
256    fn from(s: Scope) -> Self { s.to_string() }
257}
258
259#[cfg(test)]
260mod tests {
261    use super::*;
262    #[test]
263    fn custom_scope() {
264        assert_eq!(
265            Scope::Other(Cow::from("custom_scope")),
266            Scope::parse("custom_scope")
267        )
268    }
269
270    #[test]
271    fn roundabout() {
272        for scope in Scope::all() {
273            assert_eq!(scope, Scope::parse(scope.to_string()))
274        }
275    }
276
277    #[test]
278    #[allow(deprecated)]
279    fn no_deprecated() {
280        for scope in Scope::all() {
281            assert!(scope != Scope::ChannelSubscriptions)
282        }
283    }
284}