macro_rules! validator {
    ($operator:ident($($scopes:tt)+)) => { ... };
    ($scope:expr $(,)?) => { ... };
    ($($all:tt)+) => { ... };
    () => { ... };
}
Expand description

A validator is a way to check if a slice of scopes matches a predicate.

Uses a functional style to compose the predicate. Can be used in const context.

§Supported operators

  • not(...)
    • negates the validator passed inside, can only take one argument
  • all(...)
    • returns true if all validators passed inside return true
  • any(...)
    • returns true if any validator passed inside returns true

§Examples

use twitch_oauth2::{validator, AppAccessToken, Scope, TwitchToken as _};

let token: AppAccessToken = token();
let validator = validator!(Scope::ChatEdit, Scope::ChatRead);
assert!(validator.matches(token.scopes()));

§Multiple scopes

use twitch_oauth2::{validator, Scope};

let scopes: &[Scope] = &[Scope::ChatEdit, Scope::ChatRead];
let validator = validator!(Scope::ChatEdit, Scope::ChatRead);
assert!(validator.matches(scopes));
assert!(!validator.matches(&scopes[..1]));

§Multiple scopes with explicit all(…)

use twitch_oauth2::{validator, Scope};

let scopes: &[Scope] = &[Scope::ChatEdit, Scope::ChatRead];
let validator = validator!(all(Scope::ChatEdit, Scope::ChatRead));
assert!(validator.matches(scopes));
assert!(!validator.matches(&scopes[..1]));

§Multiple scopes with nested any(…)

use twitch_oauth2::{validator, Scope};

let scopes: &[Scope] = &[Scope::ChatEdit, Scope::ChatRead];
let validator = validator!(
    Scope::ChatEdit,
    any(Scope::ChatRead, Scope::ChannelReadSubscriptions)
);
assert!(validator.matches(scopes));
assert!(!validator.matches(&scopes[1..]));

§Not

use twitch_oauth2::{validator, Scope};

let scopes: &[Scope] = &[Scope::ChatRead];
let validator = validator!(not(Scope::ChatEdit));
assert!(validator.matches(scopes));

§Combining other validators

use twitch_oauth2::{validator, Scope, Validator};

let scopes: &[Scope] = &[
    Scope::ChatEdit,
    Scope::ChatRead,
    Scope::ModeratorManageAutoMod,
    Scope::ModerationRead,
];
const CHAT_SCOPES: Validator = validator!(all(Scope::ChatEdit, Scope::ChatRead));
const MODERATOR_SCOPES: Validator =
    validator!(Scope::ModerationRead, Scope::ModeratorManageAutoMod);
const COMBINED: Validator = validator!(CHAT_SCOPES, MODERATOR_SCOPES);
assert!(COMBINED.matches(scopes));
assert!(!COMBINED.matches(&scopes[1..]));

§Empty

use twitch_oauth2::{validator, Scope};

let scopes: &[Scope] = &[Scope::ChatRead];
let validator = validator!();
assert!(validator.matches(scopes));

§Invalid examples

§Invalid usage of not(…)

use twitch_oauth2::{Scope, validator};

let scopes: &[Scope] = &[Scope::ChatEdit, Scope::ChatRead];
let validator = validator!(not(Scope::ChatEdit, Scope::ChatRead));
assert!(validator.matches(scopes));

§Invalid operator

use twitch_oauth2::{Scope, validator};

let scopes: &[Scope] = &[Scope::ChatEdit, Scope::ChatRead];
let validator = validator!(xor(Scope::ChatEdit, Scope::ChatRead));
assert!(validator.matches(scopes));