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)]
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 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 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}