Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.3 kB View raw
1#[derive(Debug, Clone, Copy, PartialEq, Eq)] 2pub struct FsRights(u16); 3 4impl FsRights { 5 pub const READ: Self = Self(0x01); 6 pub const WRITE: Self = Self(0x02); 7 pub const CREATE: Self = Self(0x04); 8 pub const DELETE: Self = Self(0x08); 9 pub const LIST: Self = Self(0x10); 10 pub const TRAVERSE: Self = Self(0x20); 11 pub const SNAPSHOT: Self = Self(0x40); 12 13 pub const ALL: Self = Self(0x7F); 14 pub const EMPTY: Self = Self(0); 15 16 pub const TRAVERSE_INHERITABLE: Self = Self( 17 Self::READ.0 18 | Self::WRITE.0 19 | Self::CREATE.0 20 | Self::DELETE.0 21 | Self::LIST.0 22 | Self::TRAVERSE.0, 23 ); 24 25 pub const fn raw(self) -> u16 { 26 self.0 27 } 28 29 pub const fn from_raw(v: u16) -> Self { 30 Self(v) 31 } 32 33 pub const fn contains(self, other: Self) -> bool { 34 self.0 & other.0 == other.0 35 } 36 37 pub const fn restrict(self, mask: Self) -> Self { 38 Self(self.0 & mask.0) 39 } 40 41 pub const fn is_empty(self) -> bool { 42 self.0 == 0 43 } 44} 45 46#[derive(Debug, Clone, Copy, PartialEq, Eq)] 47pub struct FsCap { 48 pub object_id: u64, 49 pub generation: u64, 50 pub rights: FsRights, 51} 52 53impl FsCap { 54 pub const fn new(object_id: u64, generation: u64, rights: FsRights) -> Self { 55 Self { 56 object_id, 57 generation, 58 rights, 59 } 60 } 61 62 pub const fn root(object_id: u64, generation: u64) -> Self { 63 Self { 64 object_id, 65 generation, 66 rights: FsRights::ALL, 67 } 68 } 69 70 pub fn check_rights(&self, required: FsRights) -> Result<(), CapError> { 71 match self.rights.contains(required) { 72 true => Ok(()), 73 false => Err(CapError::InsufficientRights), 74 } 75 } 76 77 pub fn validate_generation(&self, current_generation: u64) -> Result<(), CapError> { 78 match self.generation == current_generation { 79 true => Ok(()), 80 false => Err(CapError::StaleGeneration), 81 } 82 } 83 84 pub const fn derive(&self, child_object_id: u64, child_generation: u64) -> Self { 85 Self { 86 object_id: child_object_id, 87 generation: child_generation, 88 rights: self.rights.restrict(FsRights::TRAVERSE_INHERITABLE), 89 } 90 } 91 92 pub const fn restrict(&self, mode: FsRights) -> Self { 93 Self { 94 object_id: self.object_id, 95 generation: self.generation, 96 rights: self.rights.restrict(mode), 97 } 98 } 99} 100 101#[derive(Debug, Clone, Copy, PartialEq, Eq)] 102pub enum CapError { 103 InsufficientRights, 104 StaleGeneration, 105 InvalidHandle, 106 HandleTableFull, 107 NotADirectory, 108 PathTooDeep, 109} 110 111#[cfg(test)] 112mod tests { 113 use super::*; 114 115 #[test] 116 fn rights_contains_subset() { 117 let all = FsRights::ALL; 118 assert!(all.contains(FsRights::READ)); 119 assert!(all.contains(FsRights::WRITE)); 120 assert!(all.contains(FsRights::TRAVERSE)); 121 } 122 123 #[test] 124 fn rights_restrict_narrows() { 125 let rw = FsRights::from_raw(FsRights::READ.raw() | FsRights::WRITE.raw()); 126 let restricted = FsRights::ALL.restrict(rw); 127 assert!(restricted.contains(FsRights::READ)); 128 assert!(restricted.contains(FsRights::WRITE)); 129 assert!(!restricted.contains(FsRights::CREATE)); 130 } 131 132 #[test] 133 fn cap_derive_restricts_rights() { 134 let parent = FsCap::root(1, 1); 135 let child = parent.derive(2, 1); 136 assert!(child.rights.contains(FsRights::READ)); 137 assert!(child.rights.contains(FsRights::TRAVERSE)); 138 assert!(!child.rights.contains(FsRights::SNAPSHOT)); 139 } 140 141 #[test] 142 fn cap_check_rights_rejects_missing() { 143 let cap = FsCap::new(1, 1, FsRights::READ); 144 assert!(cap.check_rights(FsRights::WRITE).is_err()); 145 } 146 147 #[test] 148 fn cap_validate_generation_stale() { 149 let cap = FsCap::new(1, 1, FsRights::ALL); 150 assert!(cap.validate_generation(2).is_err()); 151 } 152 153 #[test] 154 fn cap_restrict_only_decreases() { 155 let cap = FsCap::root(1, 1); 156 let restricted = cap.restrict(FsRights::READ); 157 assert!(restricted.rights.contains(FsRights::READ)); 158 assert!(!restricted.rights.contains(FsRights::WRITE)); 159 } 160}