1use crate::algebra::Monoid;
4use crate::permission::{AtomicPermission, PermissionSet};
5use crate::Subject;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13pub struct Resource {
14 pub id: String,
16 pub required_permissions: PermissionSet,
18 pub resource_type: String,
20}
21
22impl Resource {
23 pub fn new(id: impl Into<String>) -> Self {
25 Self {
26 id: id.into(),
27 required_permissions: PermissionSet::identity(),
28 resource_type: String::new(),
29 }
30 }
31
32 pub fn requires(mut self, perm: AtomicPermission) -> Self {
34 self.required_permissions.extend([perm]);
35 self
36 }
37
38 pub fn resource_type(mut self, rt: impl Into<String>) -> Self {
40 self.resource_type = rt.into();
41 self
42 }
43
44 pub fn can_access(&self, subject: &Subject) -> bool {
46 let effective = subject.effective_permissions();
47 self.required_permissions.is_subset_of(&effective)
48 }
49
50 pub fn missing_permissions(&self, subject: &Subject) -> PermissionSet {
52 let effective = subject.effective_permissions();
53 self.required_permissions.difference(&effective)
54 }
55}