hadoop_common/fs/permission/
fs_action.rs1use core::fmt;
2use once_cell::sync::Lazy;
3
4pub static FSACTION_VALUES: Lazy<Vec<FsAction>> = Lazy::new(FsAction::values);
6
7#[derive(Clone, Copy, PartialEq, Eq)]
9#[repr(u8)]
10pub enum FsAction {
11 None,
13 Execute,
14 Write,
15 WriteExecute,
16 Read,
17 ReadExecute,
18 ReadWrite,
19 All,
20}
21
22impl FsAction {
23 fn values() -> Vec<Self> {
24 vec![
25 Self::None,
26 Self::Execute,
27 Self::Write,
28 Self::WriteExecute,
29 Self::Read,
30 Self::ReadExecute,
31 Self::ReadWrite,
32 Self::All,
33 ]
34 }
35
36 pub fn ordinal(&self) -> usize {
37 *self as usize
38 }
39
40 pub fn symbol(&self) -> String {
42 self.to_string()
43 }
44
45 pub fn implies(&self, that: Option<&FsAction>) -> bool {
47 match that {
48 Some(that) => self.ordinal() & that.ordinal() == that.ordinal(),
49 None => false,
50 }
51 }
52
53 pub fn and(&self, that: &FsAction) -> FsAction {
55 FSACTION_VALUES[self.ordinal() & that.ordinal()]
56 }
57
58 pub fn or(&self, that: &FsAction) -> FsAction {
60 FSACTION_VALUES[self.ordinal() | that.ordinal()]
61 }
62
63 pub fn not(&self) -> FsAction {
65 FSACTION_VALUES[7 - self.ordinal()]
66 }
67
68 pub fn get_fs_action(permission: &str) -> Option<FsAction> {
70 FSACTION_VALUES
71 .iter()
72 .filter(|a| a.symbol() == permission)
73 .next()
74 .cloned()
75 }
76}
77
78impl fmt::Display for FsAction {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 match self {
81 Self::None => write!(f, "---"),
82 Self::Execute => write!(f, "--x"),
83 Self::Write => write!(f, "-w-"),
84 Self::WriteExecute => write!(f, "-wx"),
85 Self::Read => write!(f, "r--"),
86 Self::ReadExecute => write!(f, "r-x"),
87 Self::ReadWrite => write!(f, "rw-"),
88 Self::All => write!(f, "rwx"),
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_fs_action() {
99 FsAction::values()
101 .iter()
102 .for_each(|a| assert!(FsAction::All.implies(Some(a))));
103 FsAction::values().iter().for_each(|a| {
104 assert!(if *a == FsAction::None {
105 FsAction::None.implies(Some(a))
106 } else {
107 !FsAction::None.implies(Some(a))
108 });
109 });
110 FsAction::values().iter().for_each(|a| {
111 assert!(if *a == FsAction::ReadExecute
112 || *a == FsAction::Read
113 || *a == FsAction::Execute
114 || *a == FsAction::None
115 {
116 FsAction::ReadExecute.implies(Some(a))
117 } else {
118 !FsAction::ReadExecute.implies(Some(a))
119 });
120 });
121
122 assert!(FsAction::Execute == FsAction::Execute.and(&FsAction::ReadExecute));
124 assert!(FsAction::Read == FsAction::Read.and(&FsAction::ReadExecute));
125 assert!(FsAction::None == FsAction::Write.and(&FsAction::ReadExecute));
126
127 assert!(FsAction::Read == FsAction::ReadExecute.and(&FsAction::ReadWrite));
128 assert!(FsAction::None == FsAction::ReadExecute.and(&FsAction::Write));
129 assert!(FsAction::WriteExecute == FsAction::All.and(&FsAction::WriteExecute));
130 }
131}