1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
macro_rules! scope_impls {
($($i:ident,$rename:literal,$doc:literal);* $(;)? ) => {
#[doc = "Scopes for twitch."]
#[doc = ""]
#[doc = "<https://dev.twitch.tv/docs/authentication/#scopes>"]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[non_exhaustive]
#[serde(from = "String")]
#[serde(into = "String")]
pub enum Scope {
$(
#[doc = $doc]
#[doc = "\n\n"]
#[doc = "`"]
#[doc = $rename]
#[doc = "`"]
#[serde(rename = $rename)]
$i,
)*
#[doc = "Other scope that is not implemented."]
Other(Cow<'static, str>),
}
impl std::fmt::Display for Scope {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Scope::Other(s) => &s,
$(
Scope::$i => $rename,
)*
})
}
}
impl Scope {
#[doc = "Get a vec of all defined twitch [Scopes][Scope]."]
#[doc = "\n\n"]
#[doc = "Please note that this may not work for you, as some auth flows and \"apis\" don't accept all scopes"]
pub fn all() -> Vec<Scope> {
vec![
$(Scope::$i,)*
]
}
#[doc = "Make a scope from a cow string"]
pub fn parse<C>(s: C) -> Scope where C: Into<Cow<'static, str>> {
use std::borrow::Borrow;
let s = s.into();
match s.borrow() {
$($rename => {Scope::$i})*,
_ => Scope::Other(s)
}
}
}
};
}
scope_impls!(
AnalyticsReadExtensions, "analytics:read:extensions", "View analytics data for the Twitch Extensions owned by the authenticated account.";
AnalyticsReadGames, "analytics:read:games", "View analytics data for the games owned by the authenticated account.";
BitsRead, "bits:read", "View Bits information for a channel.";
ChannelEditCommercial, "channel:edit:commercial", "Run commercials on a channel.";
ChannelManageBroadcast, "channel:manage:broadcast", "Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags.";
ChannelManageExtensions, "channel:manage:extensions", "Manage a channel’s Extension configuration, including activating Extensions.";
ChannelManageRedemptions, "channel:manage:redemptions", "Manage Channel Points custom rewards and their redemptions on a channel.";
ChannelManageVideos, "channel:manage:videos", "Manage a channel’s videos, including deleting videos.";
ChannelModerate, "channel:moderate", "Perform moderation actions in a channel. The user requesting the scope must be a moderator in the channel.";
ChannelReadEditors, "channel:read:editors", "View a list of users with the editor role for a channel.";
ChannelReadHypeTrain, "channel:read:hype_train", "View Hype Train information for a channel.";
ChannelReadRedemptions, "channel:read:redemptions", "View Channel Points custom rewards and their redemptions on a channel.";
ChannelReadStreamKey, "channel:read:stream_key", "View an authorized user’s stream key.";
ChannelReadSubscriptions, "channel:read:subscriptions", "View a list of all subscribers to a channel and check if a user is subscribed to a channel.";
ChannelSubscriptions, "channel_subscriptions", "\\[DEPRECATED\\] Read all subscribers to your channel.";
ChatEdit, "chat:edit", "Send live stream chat and rooms messages.";
ChatRead, "chat:read", "View live stream chat and rooms messages.";
ClipsEdit, "clips:edit", "Manage Clips for a channel.";
ModerationRead, "moderation:read", "View a channel’s moderation data including Moderators, Bans, Timeouts, and Automod settings.";
UserEdit, "user:edit", "Manage a user object.";
UserEditBroadcast, "user:edit:broadcast", "Edit your channel's broadcast configuration, including extension configuration. (This scope implies user:read:broadcast capability.)";
UserEditFollows, "user:edit:follows", "Edit a user’s follows.";
UserManageBlockedUsers, "user:manage:blocked_users", "Manage the block list of a user.";
UserReadBlockedUsers, "user:read:blocked_users", "View the block list of a user.";
UserReadBroadcast, "user:read:broadcast", "View a user’s broadcasting configuration, including Extension configurations.";
UserReadEmail, "user:read:email", "Read an authorized user’s email address.";
WhispersEdit, "whispers:edit", "Send whisper messages.";
WhispersRead, "whispers:read", "View your whisper messages.";
);
impl Scope {
pub fn as_oauth_scope(&self) -> oauth2::Scope { oauth2::Scope::new(self.to_string()) }
}
impl From<oauth2::Scope> for Scope {
fn from(scope: oauth2::Scope) -> Self { Scope::parse(scope.to_string()) }
}
impl From<String> for Scope {
fn from(s: String) -> Self { Scope::parse(s) }
}
impl From<Scope> for String {
fn from(s: Scope) -> Self { s.to_string() }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn custom_scope() {
assert_eq!(
Scope::Other(Cow::from("custom_scope")),
Scope::parse("custom_scope")
)
}
#[test]
fn roundabout() {
for scope in Scope::all() {
assert_eq!(scope, Scope::parse(scope.to_string()))
}
}
}