use std::ops::{BitOr, BitOrAssign};
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Scopes(u16);
macro_rules! define_scopes {
( $(
#[doc = $doc:literal]
$scope:ident: $shift:literal, $str:literal;
)* ) => {
define_scopes! {@ $(
#[doc = $doc]
$scope: 1 << $shift, $str;
)* }
};
(@ $(
#[doc = $doc:literal]
$scope:ident: $bit:expr, $str:literal;
)* ) => {
$(
#[allow(non_upper_case_globals)]
impl Scopes {
#[doc = $doc]
pub const $scope: Self = Self($bit);
}
)*
impl Scopes {
const fn contains(self, bit: u16) -> bool {
(self.0 & bit) > 0
}
pub(crate) fn format(self, s: &mut String, separator: char) {
let mut first_scope = true;
$(
if self.contains($bit) {
if !first_scope {
s.push(separator);
}
s.push_str($str);
#[allow(unused_assignments)]
{
first_scope = false;
}
}
)*
}
}
};
}
define_scopes! {
ChatRead: 0, "chat.read";
ChatWrite: 1, "chat.write";
ChatWriteManage: 2, "chat.write_manage";
Delegate: 3, "delegate";
ForumWrite: 4, "forum.write";
FriendsRead: 5, "friends.read";
Identify: 6, "identify";
Public: 7, "public";
}
impl Default for Scopes {
fn default() -> Self {
Self::Public
}
}
impl BitOr for Scopes {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0.bitor(rhs.0))
}
}
impl BitOrAssign for Scopes {
fn bitor_assign(&mut self, rhs: Self) {
self.0.bitor_assign(rhs.0);
}
}