use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Scope {
PreferenceRead,
PreferenceWrite,
EmailRead,
EngineRead,
EngineWrite,
ChallengeRead,
ChallengeWrite,
ChallengeBulk,
StudyRead,
StudyWrite,
TournamentWrite,
RacerWrite,
PuzzleRead,
PuzzleWrite,
TeamRead,
TeamWrite,
TeamLead,
FollowRead,
FollowWrite,
MsgWrite,
BoardPlay,
BotPlay,
WebMod,
}
impl Scope {
pub const ALL: [Scope; 23] = [
Scope::PreferenceRead,
Scope::PreferenceWrite,
Scope::EmailRead,
Scope::EngineRead,
Scope::EngineWrite,
Scope::ChallengeRead,
Scope::ChallengeWrite,
Scope::ChallengeBulk,
Scope::StudyRead,
Scope::StudyWrite,
Scope::TournamentWrite,
Scope::RacerWrite,
Scope::PuzzleRead,
Scope::PuzzleWrite,
Scope::TeamRead,
Scope::TeamWrite,
Scope::TeamLead,
Scope::FollowRead,
Scope::FollowWrite,
Scope::MsgWrite,
Scope::BoardPlay,
Scope::BotPlay,
Scope::WebMod,
];
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Scope::PreferenceRead => "preference:read",
Scope::PreferenceWrite => "preference:write",
Scope::EmailRead => "email:read",
Scope::EngineRead => "engine:read",
Scope::EngineWrite => "engine:write",
Scope::ChallengeRead => "challenge:read",
Scope::ChallengeWrite => "challenge:write",
Scope::ChallengeBulk => "challenge:bulk",
Scope::StudyRead => "study:read",
Scope::StudyWrite => "study:write",
Scope::TournamentWrite => "tournament:write",
Scope::RacerWrite => "racer:write",
Scope::PuzzleRead => "puzzle:read",
Scope::PuzzleWrite => "puzzle:write",
Scope::TeamRead => "team:read",
Scope::TeamWrite => "team:write",
Scope::TeamLead => "team:lead",
Scope::FollowRead => "follow:read",
Scope::FollowWrite => "follow:write",
Scope::MsgWrite => "msg:write",
Scope::BoardPlay => "board:play",
Scope::BotPlay => "bot:play",
Scope::WebMod => "web:mod",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
Self::ALL.into_iter().find(|scope| scope.as_str() == value)
}
}
impl fmt::Display for Scope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trips_every_scope() {
for scope in Scope::ALL {
assert_eq!(Scope::parse(scope.as_str()), Some(scope));
}
}
#[test]
fn unknown_scope_is_none() {
assert_eq!(Scope::parse("does:notexist"), None);
}
#[test]
fn uses_colon_separated_wire_format() {
assert_eq!(Scope::BoardPlay.as_str(), "board:play");
assert_eq!(Scope::WebMod.to_string(), "web:mod");
}
}