Skip to main content

steel_core/permission/
subject.rs

1use std::collections::BTreeMap;
2
3use uuid::Uuid;
4
5use super::{PermissionMetadataSet, PermissionSet};
6
7/// Persisted permission state for one player or other internal subject.
8#[derive(Clone, Debug, Default, PartialEq, Eq)]
9pub struct PermissionSubjectState {
10    groups: Vec<String>,
11    overrides: PermissionSet,
12    metadata_overrides: PermissionMetadataSet,
13}
14
15impl PermissionSubjectState {
16    /// Creates a persisted subject snapshot.
17    #[must_use]
18    pub const fn new(groups: Vec<String>, overrides: PermissionSet) -> Self {
19        Self {
20            groups,
21            overrides,
22            metadata_overrides: PermissionMetadataSet::new(),
23        }
24    }
25
26    /// Creates a persisted subject snapshot with metadata overrides.
27    #[must_use]
28    pub const fn new_with_metadata(
29        groups: Vec<String>,
30        overrides: PermissionSet,
31        metadata_overrides: PermissionMetadataSet,
32    ) -> Self {
33        Self {
34            groups,
35            overrides,
36            metadata_overrides,
37        }
38    }
39
40    /// Returns assigned group names in persisted order.
41    #[must_use]
42    pub fn groups(&self) -> &[String] {
43        &self.groups
44    }
45
46    /// Returns direct permission overrides.
47    #[must_use]
48    pub const fn overrides(&self) -> &PermissionSet {
49        &self.overrides
50    }
51
52    /// Returns direct metadata overrides.
53    #[must_use]
54    pub const fn metadata_overrides(&self) -> &PermissionMetadataSet {
55        &self.metadata_overrides
56    }
57
58    /// Returns whether this subject has no persisted permission state.
59    #[must_use]
60    pub fn is_empty(&self) -> bool {
61        self.groups.is_empty()
62            && self.overrides.entries().is_empty()
63            && self.metadata_overrides.is_empty()
64    }
65
66    /// Splits the snapshot into assigned groups and overrides.
67    #[must_use]
68    pub fn into_parts(self) -> (Vec<String>, PermissionSet, PermissionMetadataSet) {
69        (self.groups, self.overrides, self.metadata_overrides)
70    }
71}
72
73/// In-memory index of persisted player permission snapshots.
74#[derive(Clone, Debug, Default, PartialEq, Eq)]
75pub struct PermissionSubjectIndex {
76    states: BTreeMap<Uuid, PermissionSubjectState>,
77}
78
79impl PermissionSubjectIndex {
80    /// Creates an empty subject index.
81    #[must_use]
82    pub const fn new() -> Self {
83        Self {
84            states: BTreeMap::new(),
85        }
86    }
87
88    /// Returns one player's persisted permission state.
89    #[must_use]
90    pub fn get(&self, uuid: Uuid) -> Option<&PermissionSubjectState> {
91        self.states.get(&uuid)
92    }
93
94    /// Inserts or replaces one player's persisted permission state.
95    pub fn set(&mut self, uuid: Uuid, state: PermissionSubjectState) {
96        self.states.insert(uuid, state);
97    }
98
99    /// Removes one player's persisted permission state.
100    pub fn remove(&mut self, uuid: Uuid) -> Option<PermissionSubjectState> {
101        self.states.remove(&uuid)
102    }
103
104    /// Returns all entries sorted by UUID.
105    pub fn entries(&self) -> impl Iterator<Item = (Uuid, &PermissionSubjectState)> {
106        self.states.iter().map(|(uuid, state)| (*uuid, state))
107    }
108
109    /// Returns the number of persisted subjects.
110    #[must_use]
111    pub fn len(&self) -> usize {
112        self.states.len()
113    }
114
115    /// Returns whether no subjects have persisted permission state.
116    #[must_use]
117    pub fn is_empty(&self) -> bool {
118        self.states.is_empty()
119    }
120}