hdfs_native/
acl.rs

1use std::fmt::Display;
2
3use crate::proto::hdfs::{
4    acl_entry_proto::{AclEntryScopeProto, AclEntryTypeProto, FsActionProto},
5    AclEntryProto, AclStatusProto,
6};
7
8#[derive(Clone, Debug, PartialEq)]
9pub enum AclEntryType {
10    User,
11    Group,
12    Mask,
13    Other,
14}
15
16impl From<AclEntryType> for AclEntryTypeProto {
17    fn from(value: AclEntryType) -> Self {
18        match value {
19            AclEntryType::User => AclEntryTypeProto::User,
20            AclEntryType::Group => AclEntryTypeProto::Group,
21            AclEntryType::Mask => AclEntryTypeProto::Mask,
22            AclEntryType::Other => AclEntryTypeProto::Other,
23        }
24    }
25}
26
27impl From<AclEntryTypeProto> for AclEntryType {
28    fn from(value: AclEntryTypeProto) -> Self {
29        match value {
30            AclEntryTypeProto::User => AclEntryType::User,
31            AclEntryTypeProto::Group => AclEntryType::Group,
32            AclEntryTypeProto::Mask => AclEntryType::Mask,
33            AclEntryTypeProto::Other => AclEntryType::Other,
34        }
35    }
36}
37
38impl From<&str> for AclEntryType {
39    fn from(value: &str) -> Self {
40        match value.to_ascii_lowercase().as_ref() {
41            "user" => AclEntryType::User,
42            "group" => AclEntryType::Group,
43            "mask" => AclEntryType::Mask,
44            "other" => AclEntryType::Other,
45            _ => panic!("Unknown ACL entry type {}", value),
46        }
47    }
48}
49
50impl From<String> for AclEntryType {
51    fn from(value: String) -> Self {
52        Self::from(value.as_ref())
53    }
54}
55
56impl Display for AclEntryType {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(
59            f,
60            "{}",
61            match self {
62                AclEntryType::User => "user",
63                AclEntryType::Group => "group",
64                AclEntryType::Mask => "mask",
65                AclEntryType::Other => "other",
66            }
67        )
68    }
69}
70
71#[derive(Clone, Debug, PartialEq)]
72pub enum AclEntryScope {
73    Access,
74    Default,
75}
76
77impl From<AclEntryScope> for AclEntryScopeProto {
78    fn from(value: AclEntryScope) -> Self {
79        match value {
80            AclEntryScope::Access => AclEntryScopeProto::Access,
81            AclEntryScope::Default => AclEntryScopeProto::Default,
82        }
83    }
84}
85
86impl From<AclEntryScopeProto> for AclEntryScope {
87    fn from(value: AclEntryScopeProto) -> Self {
88        match value {
89            AclEntryScopeProto::Access => AclEntryScope::Access,
90            AclEntryScopeProto::Default => AclEntryScope::Default,
91        }
92    }
93}
94
95impl From<&str> for AclEntryScope {
96    fn from(value: &str) -> Self {
97        match value.to_ascii_lowercase().as_ref() {
98            "access" => AclEntryScope::Access,
99            "default" => AclEntryScope::Default,
100            _ => panic!("Unknown ACL entry scope {}", value),
101        }
102    }
103}
104
105impl From<String> for AclEntryScope {
106    fn from(value: String) -> Self {
107        Self::from(value.as_ref())
108    }
109}
110
111impl Display for AclEntryScope {
112    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113        write!(
114            f,
115            "{}",
116            match self {
117                AclEntryScope::Access => "access",
118                AclEntryScope::Default => "default",
119            }
120        )
121    }
122}
123
124#[derive(Clone, Debug, PartialEq)]
125pub enum FsAction {
126    None = 0,
127    Execute = 1,
128    Write = 2,
129    WriteExecute = 3,
130    Read = 4,
131    ReadExecute = 5,
132    ReadWrite = 6,
133    PermAll = 7,
134}
135
136impl From<FsAction> for FsActionProto {
137    fn from(value: FsAction) -> Self {
138        match value {
139            FsAction::None => FsActionProto::None,
140            FsAction::Execute => FsActionProto::Execute,
141            FsAction::Write => FsActionProto::Write,
142            FsAction::WriteExecute => FsActionProto::WriteExecute,
143            FsAction::Read => FsActionProto::Read,
144            FsAction::ReadExecute => FsActionProto::ReadExecute,
145            FsAction::ReadWrite => FsActionProto::ReadWrite,
146            FsAction::PermAll => FsActionProto::PermAll,
147        }
148    }
149}
150
151impl From<FsActionProto> for FsAction {
152    fn from(value: FsActionProto) -> Self {
153        match value {
154            FsActionProto::None => FsAction::None,
155            FsActionProto::Execute => FsAction::Execute,
156            FsActionProto::Write => FsAction::Write,
157            FsActionProto::WriteExecute => FsAction::WriteExecute,
158            FsActionProto::Read => FsAction::Read,
159            FsActionProto::ReadExecute => FsAction::ReadExecute,
160            FsActionProto::ReadWrite => FsAction::ReadWrite,
161            FsActionProto::PermAll => FsAction::PermAll,
162        }
163    }
164}
165
166impl From<&str> for FsAction {
167    fn from(value: &str) -> Self {
168        match value {
169            "---" => FsAction::None,
170            "--x" => FsAction::Execute,
171            "-w-" => FsAction::Write,
172            "-wx" => FsAction::WriteExecute,
173            "r--" => FsAction::Read,
174            "r-x" => FsAction::ReadExecute,
175            "rw-" => FsAction::ReadWrite,
176            "rwx" => FsAction::PermAll,
177            _ => panic!("Unknown file system permission {}", value),
178        }
179    }
180}
181
182impl From<String> for FsAction {
183    fn from(value: String) -> Self {
184        Self::from(value.as_ref())
185    }
186}
187
188impl Display for FsAction {
189    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190        write!(
191            f,
192            "{}",
193            match self {
194                FsAction::None => "---",
195                FsAction::Execute => "--x",
196                FsAction::Write => "-w-",
197                FsAction::WriteExecute => "-wx",
198                FsAction::Read => "r--",
199                FsAction::ReadExecute => "r-x",
200                FsAction::ReadWrite => "rw-",
201                FsAction::PermAll => "rwx",
202            }
203        )
204    }
205}
206
207#[derive(Clone, Debug, PartialEq)]
208pub struct AclEntry {
209    pub r#type: AclEntryType,
210    pub scope: AclEntryScope,
211    pub permissions: FsAction,
212    pub name: Option<String>,
213}
214
215impl AclEntry {
216    /// Create a new ACL entry.
217    pub fn new(
218        r#type: impl Into<AclEntryType>,
219        scope: impl Into<AclEntryScope>,
220        permissions: impl Into<FsAction>,
221        name: Option<String>,
222    ) -> Self {
223        Self {
224            r#type: r#type.into(),
225            scope: scope.into(),
226            permissions: permissions.into(),
227            name,
228        }
229    }
230}
231
232impl From<AclEntry> for AclEntryProto {
233    fn from(value: AclEntry) -> Self {
234        let r#type: AclEntryTypeProto = value.r#type.into();
235        let scope: AclEntryScopeProto = value.scope.into();
236        let permissions: FsActionProto = value.permissions.into();
237        Self {
238            r#type: r#type as i32,
239            scope: scope as i32,
240            permissions: permissions as i32,
241            name: value.name,
242        }
243    }
244}
245
246impl FromIterator<AclEntry> for Vec<AclEntryProto> {
247    fn from_iter<T: IntoIterator<Item = AclEntry>>(iter: T) -> Self {
248        iter.into_iter().map(AclEntryProto::from).collect()
249    }
250}
251
252impl From<AclEntryProto> for AclEntry {
253    fn from(value: AclEntryProto) -> Self {
254        Self {
255            r#type: value.r#type().into(),
256            scope: value.scope().into(),
257            permissions: value.permissions().into(),
258            name: value.name,
259        }
260    }
261}
262
263impl FromIterator<AclEntryProto> for Vec<AclEntry> {
264    fn from_iter<T: IntoIterator<Item = AclEntryProto>>(iter: T) -> Self {
265        iter.into_iter().map(AclEntry::from).collect()
266    }
267}
268
269pub struct AclStatus {
270    pub owner: String,
271    pub group: String,
272    pub sticky: bool,
273    pub entries: Vec<AclEntry>,
274    pub permission: u16,
275}
276
277impl From<AclStatusProto> for AclStatus {
278    fn from(value: AclStatusProto) -> Self {
279        Self {
280            owner: value.owner,
281            group: value.group,
282            sticky: value.sticky,
283            entries: value.entries.into_iter().collect(),
284            permission: value.permission.unwrap().perm as u16,
285        }
286    }
287}