Skip to main content

wowlab_parsers/parsers/access/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// Set of access rules controlling who can view a resource.
4#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
5#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
6#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
7pub struct AccessControl {
8    pub rules: Vec<AccessRule>,
9}
10
11/// A single access-control grant (public, Discord guild, or friend list).
12#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
13#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
14#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
15#[serde(tag = "type", content = "target", rename_all = "snake_case")]
16// #t(rust_non_exhaustive_on_public) stable access rule types matching the access control grammar
17pub enum AccessRule {
18    Public,
19    Discord(String),
20    Friends(String),
21}
22
23impl AccessControl {
24    #[must_use]
25    pub fn private() -> Self {
26        Self { rules: vec![] }
27    }
28
29    #[must_use]
30    pub fn public() -> Self {
31        Self {
32            rules: vec![AccessRule::Public],
33        }
34    }
35
36    #[must_use]
37    pub fn is_private(&self) -> bool {
38        self.rules.is_empty()
39    }
40
41    #[must_use]
42    pub fn is_public(&self) -> bool {
43        self.rules.iter().any(|r| matches!(r, AccessRule::Public))
44    }
45
46    pub fn discord_guild_ids(&self) -> impl Iterator<Item = &str> {
47        self.rules.iter().filter_map(|r| match r {
48            AccessRule::Discord(id) => Some(id.as_str()),
49            _ => None,
50        })
51    }
52
53    pub fn friend_list_ids(&self) -> impl Iterator<Item = &str> {
54        self.rules.iter().filter_map(|r| match r {
55            AccessRule::Friends(id) => Some(id.as_str()),
56            _ => None,
57        })
58    }
59}
60
61impl std::fmt::Display for AccessControl {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        let parts: Vec<String> = self
64            .rules
65            .iter()
66            .map(|r| match r {
67                AccessRule::Public => "public".to_string(),
68                AccessRule::Discord(id) => format!("discord:{id}"),
69                AccessRule::Friends(id) => format!("friends:{id}"),
70            })
71            .collect();
72
73        write!(f, "{}", parts.join(","))
74    }
75}