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 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}