1pub 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, Hash)]
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)] $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 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 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 n_deprecated = [$(
141 $(stringify!($depr),)*
142 )*].len();
143 let slice = [$(
144 $(#[cfg($cfg)])*
145 $rename,
146 )*];
147 let n_scopes = slice.len();
148 let slice = &slice[..(n_scopes - n_deprecated)];
149 let mut slice_sorted = [$(
150 $(#[cfg($cfg)])*
151 $rename,
152 )*];
153 let slice_sorted = &mut slice_sorted[..(n_scopes - n_deprecated)];
154 slice_sorted.sort();
155 for (scope, sorted) in slice.iter().zip(slice_sorted.iter()) {
156 assert_eq!(scope, sorted);
157 }
158 assert_eq!(slice, slice_sorted);
159 }
160 };
161}
162
163scope_impls!(
199 AnalyticsReadExtensions, scope: "analytics:read:extensions", doc: "View analytics data for the Twitch Extensions owned by the authenticated account.";
200 AnalyticsReadGames, scope: "analytics:read:games", doc: "View analytics data for the games owned by the authenticated account.";
201 BitsRead, scope: "bits:read", doc: "View Bits information for a channel.";
202 ChannelBot, scope: "channel:bot", doc: "Joins your channel’s chatroom as a bot user, and perform chat-related actions as that user.";
203 ChannelEditCommercial, scope: "channel:edit:commercial", doc: "Run commercials on a channel.";
204 ChannelManageAds, scope: "channel:manage:ads", doc: "Manage ads schedule on a channel.";
205 ChannelManageBroadcast, scope: "channel:manage:broadcast", doc: "Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags.";
206 ChannelManageClips, scope: "channel:manage:clips", doc: "Manage Clips for a channel.";
207 ChannelManageExtensions, scope: "channel:manage:extensions", doc: "Manage a channel’s Extension configuration, including activating Extensions.";
208 ChannelManageGuestStar, scope: "channel:manage:guest_star", doc: "Manage Guest Star for your channel.";
209 ChannelManageModerators, scope: "channel:manage:moderators", doc: "Add or remove the moderator role from users in your channel.";
210 ChannelManagePolls, scope: "channel:manage:polls", doc: "Manage a channel’s polls.";
211 ChannelManagePredictions, scope: "channel:manage:predictions", doc: "Manage of channel’s Channel Points Predictions";
212 ChannelManageRaids, scope: "channel:manage:raids", doc: "Manage a channel raiding another channel.";
213 ChannelManageRedemptions, scope: "channel:manage:redemptions", doc: "Manage Channel Points custom rewards and their redemptions on a channel.";
214 ChannelManageSchedule, scope: "channel:manage:schedule", doc: "Manage a channel’s stream schedule.";
215 ChannelManageVideos, scope: "channel:manage:videos", doc: "Manage a channel’s videos, including deleting videos.";
216 ChannelManageVips, scope: "channel:manage:vips", doc: "Add or remove the VIP role from users in your channel.";
217 ChannelModerate, scope: "channel:moderate", doc: "Perform moderation actions in a channel.";
218 ChannelReadAds, scope: "channel:read:ads", doc: "Read the ads schedule and details on your channel.";
219 ChannelReadCharity, scope: "channel:read:charity", doc: "Read charity campaign details and user donations on your channel.";
220 ChannelReadEditors, scope: "channel:read:editors", doc: "View a list of users with the editor role for a channel.";
221 ChannelReadGoals, scope: "channel:read:goals", doc: "View Creator Goals for a channel.";
222 ChannelReadGuestStar, scope: "channel:read:guest_star", doc: "Read Guest Star details for your channel.";
223 ChannelReadHypeTrain, scope: "channel:read:hype_train", doc: "View Hype Train information for a channel.";
224 ChannelReadPolls, scope: "channel:read:polls", doc: "View a channel’s polls.";
225 ChannelReadPredictions, scope: "channel:read:predictions", doc: "View a channel’s Channel Points Predictions.";
226 ChannelReadRedemptions, scope: "channel:read:redemptions", doc: "View Channel Points custom rewards and their redemptions on a channel.";
227 ChannelReadStreamKey, scope: "channel:read:stream_key", doc: "View an authorized user’s stream key.";
228 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.";
229 ChannelReadVips, scope: "channel:read:vips", doc: "Read the list of VIPs in your channel.";
230 ChatEdit, scope: "chat:edit", doc: "Send chat messages to a chatroom using an IRC connection.";
231 ChatRead, scope: "chat:read", doc: "View chat messages sent in a chatroom using an IRC connection.";
232 ClipsEdit, scope: "clips:edit", doc: "Manage Clips for a channel.";
233 EditorManageClips, scope: "editor:manage:clips", doc: "Manage Clips as an editor.";
234 ModerationRead, scope: "moderation:read", doc: "View a channel’s moderation data including Moderators, Bans, Timeouts, and Automod settings.";
235 ModeratorManageAnnouncements, scope: "moderator:manage:announcements", doc: "Send announcements in channels where you have the moderator role.";
236 ModeratorManageAutoMod, scope: "moderator:manage:automod", doc: "Manage messages held for review by AutoMod in channels where you are a moderator.";
237 ModeratorManageAutomodSettings, scope: "moderator:manage:automod_settings", doc: "Manage a broadcaster’s AutoMod settings.";
238 ModeratorManageBannedUsers, scope: "moderator:manage:banned_users", doc: "Ban and unban users.";
239 ModeratorManageBlockedTerms, scope: "moderator:manage:blocked_terms", doc: "Manage a broadcaster’s list of blocked terms.";
240 ModeratorManageChatMessages, scope: "moderator:manage:chat_messages", doc: "Delete chat messages in channels where you have the moderator role";
241 ModeratorManageChatSettings, scope: "moderator:manage:chat_settings", doc: "Manage a broadcaster’s chat room settings.";
242 ModeratorManageGuestStar, scope: "moderator:manage:guest_star", doc: "Manage Guest Star for channels where you are a Guest Star moderator.";
243 ModeratorManageShieldMode, scope: "moderator:manage:shield_mode", doc: "Manage a broadcaster’s Shield Mode status.";
244 ModeratorManageShoutouts, scope: "moderator:manage:shoutouts", doc: "Manage a broadcaster’s shoutouts.";
245 ModeratorManageSuspiciousUsers, scope: "moderator:manage:suspicious_users", doc: "Manage suspicious user statuses in channels where the user has the moderator role.";
246 ModeratorManageUnbanRequests, scope: "moderator:manage:unban_requests", doc: "Manage a broadcaster’s unban requests.";
247 ModeratorManageWarnings, scope: "moderator:manage:warnings", doc: "Warn users in channels where you have the moderator role.";
248 ModeratorReadAutomodSettings, scope: "moderator:read:automod_settings", doc: "View a broadcaster’s AutoMod settings.";
249 ModeratorReadBannedUsers, scope: "moderator:read:banned_users", doc: "Read the list of bans or unbans in channels where you have the moderator role.";
250 ModeratorReadBlockedTerms, scope: "moderator:read:blocked_terms", doc: "View a broadcaster’s list of blocked terms.";
251 ModeratorReadChatMessages, scope: "moderator:read:chat_messages", doc: "Read deleted chat messages in channels where you have the moderator role.";
252 ModeratorReadChatSettings, scope: "moderator:read:chat_settings", doc: "View a broadcaster’s chat room settings.";
253 ModeratorReadChatters, scope: "moderator:read:chatters", doc: "View the chatters in a broadcaster’s chat room.";
254 ModeratorReadFollowers, scope: "moderator:read:followers", doc: "Read the followers of a broadcaster.";
255 ModeratorReadGuestStar, scope: "moderator:read:guest_star", doc: "Read Guest Star details for channels where you are a Guest Star moderator.";
256 ModeratorReadModerators, scope: "moderator:read:moderators", doc: "Read the list of moderators in channels where you have the moderator role.";
257 ModeratorReadShieldMode, scope: "moderator:read:shield_mode", doc: "View a broadcaster’s Shield Mode status.";
258 ModeratorReadShoutouts, scope: "moderator:read:shoutouts", doc: "View a broadcaster’s shoutouts.";
259 ModeratorReadSuspiciousUsers, scope: "moderator:read:suspicious_users", doc: "Read chat messages from suspicious users and see users flagged as suspicious in channels where the user has the moderator role.";
260 ModeratorReadUnbanRequests, scope: "moderator:read:unban_requests", doc: "View a broadcaster’s unban requests.";
261 ModeratorReadVips, scope: "moderator:read:vips", doc: "Read the list of VIPs in channels where you have the moderator role.";
262 ModeratorReadWarnings, scope: "moderator:read:warnings", doc: "Read warnings in channels where you have the moderator role.";
263 UserBot, scope: "user:bot", doc: "Join a specified chat channel as your user and appear as a bot, and perform chat-related actions as your user.";
264 UserEdit, scope: "user:edit", doc: "Manage a user object.";
265 UserEditBroadcast, scope: "user:edit:broadcast", doc: "View and edit a user’s broadcasting configuration, including Extension configurations.";
266 UserManageBlockedUsers, scope: "user:manage:blocked_users", doc: "Manage the block list of a user.";
267 UserManageChatColor, scope: "user:manage:chat_color", doc: "Update the color used for the user’s name in chat.";
268 UserManageWhispers, scope: "user:manage:whispers", doc: "Receive whispers sent to your user, and send whispers on your user’s behalf.";
269 UserReadBlockedUsers, scope: "user:read:blocked_users", doc: "View the block list of a user.";
270 UserReadBroadcast, scope: "user:read:broadcast", doc: "View a user’s broadcasting configuration, including Extension configurations.";
271 UserReadChat, scope: "user:read:chat", doc: "Receive chatroom messages and informational notifications relating to a channel’s chatroom.";
272 UserReadEmail, scope: "user:read:email", doc: "View a user’s email address.";
273 UserReadEmotes, scope: "user:read:emotes", doc: "View emotes available to a user";
274 UserReadFollows, scope: "user:read:follows", doc: "View the list of channels a user follows.";
275 UserReadModeratedChannels, scope: "user:read:moderated_channels", doc: "Read the list of channels you have moderator privileges in.";
276 UserReadSubscriptions, scope: "user:read:subscriptions", doc: "View if an authorized user is subscribed to specific channels.";
277 UserReadWhispers, scope: "user:read:whispers", doc: "Receive whispers sent to your user.";
278 UserWriteChat, scope: "user:write:chat", doc: "Send chat messages to a chatroom.";
279 WhispersRead, scope: "whispers:read", doc: "Receive whisper messages for your user using PubSub.";
280
281 #[deprecated(note = "Use `ChannelReadSubscriptions` (`channel:read:subscriptions`) instead")]
284 ChannelSubscriptions, scope: "channel_subscriptions", doc: "Read all subscribers to your channel.";
285 #[deprecated(note = "Not used anymore, see https://discuss.dev.twitch.tv/t/deprecation-of-create-and-delete-follows-api-endpoints/32351")]
286 UserEditFollows, scope: "user:edit:follows", doc: "\\[DEPRECATED\\] Was previously used for “Create User Follows” and “Delete User Follows.";
287 #[deprecated(note = "Use `UserManageWhispers` (`user:manage:whispers`) instead")]
288 WhispersEdit, scope: "whispers:edit", doc: "\\[DEPRECATED\\] Send whisper messages.";
289);
290
291impl Scope {
292 pub const fn to_validator(self) -> Validator { Validator::scope(self) }
294}
295
296impl std::borrow::Borrow<str> for Scope {
297 fn borrow(&self) -> &str { self.as_str() }
298}
299
300impl From<String> for Scope {
301 fn from(s: String) -> Self { Scope::parse(s) }
302}
303
304impl From<Scope> for String {
305 fn from(s: Scope) -> Self { s.to_string() }
306}
307
308#[cfg(test)]
309mod tests {
310 use super::*;
311 #[test]
312 fn custom_scope() {
313 assert_eq!(
314 Scope::Other(Cow::from("custom_scope")),
315 Scope::parse("custom_scope")
316 )
317 }
318
319 #[test]
320 fn roundabout() {
321 for scope in Scope::all() {
322 assert_eq!(scope, Scope::parse(scope.to_string()))
323 }
324 }
325
326 #[test]
327 #[allow(deprecated)]
328 fn no_deprecated() {
329 for scope in Scope::all() {
330 assert!(scope != Scope::ChannelSubscriptions)
331 }
332 }
333}