didbot_scope/
transition.rs1use std::fmt;
4
5use crate::pattern::under_prefix;
6use crate::{AccountAction, AccountAttr, NsidPattern, Scope, ScopeParseError};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub enum Transition {
16 Generic,
20 ChatBsky,
22 Email,
24}
25
26impl Transition {
27 pub(crate) fn as_str(self) -> &'static str {
28 match self {
29 Transition::Generic => "generic",
30 Transition::ChatBsky => "chat.bsky",
31 Transition::Email => "email",
32 }
33 }
34
35 pub(crate) fn parse(s: &str) -> Result<Self, ScopeParseError> {
36 match s {
37 "generic" => Ok(Transition::Generic),
38 "chat.bsky" => Ok(Transition::ChatBsky),
39 "email" => Ok(Transition::Email),
40 other => Err(ScopeParseError::UnknownTransition(other.to_owned())),
41 }
42 }
43
44 pub(crate) fn covers(self, scope: &Scope) -> bool {
51 match (self, scope) {
52 (Transition::Generic, Scope::Repo { .. } | Scope::Blob { .. }) => true,
53 (Transition::Generic, Scope::Rpc { method, .. }) => !reaches_chat_bsky(method),
54 (
55 Transition::ChatBsky,
56 Scope::Repo {
57 collection: NsidPattern::Exact(nsid) | NsidPattern::Prefix(nsid),
58 ..
59 },
60 )
61 | (
62 Transition::ChatBsky,
63 Scope::Rpc {
64 method: NsidPattern::Exact(nsid) | NsidPattern::Prefix(nsid),
65 ..
66 },
67 ) => under_prefix("chat.bsky", nsid) || nsid == "chat.bsky",
68 (
69 Transition::Email,
70 Scope::Account {
71 attr: AccountAttr::Email,
72 action: AccountAction::Read,
73 },
74 ) => true,
75 _ => false,
76 }
77 }
78}
79
80fn reaches_chat_bsky(method: &NsidPattern) -> bool {
85 match method {
86 NsidPattern::Any => true,
87 NsidPattern::Exact(nsid) => under_prefix("chat.bsky", nsid),
88 NsidPattern::Prefix(prefix) => {
89 under_prefix("chat.bsky", prefix) || under_prefix(prefix, "chat.bsky")
90 }
91 }
92}
93
94impl fmt::Display for Transition {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "transition:{}", self.as_str())
97 }
98}