1use fidl_fuchsia_io as fio;
6
7pub use cm_types::{
8 Availability, BorrowedName, BoundedName, DeliveryType, DependencyType, HandleType, Name,
9 OnTerminate, ParseError, Path, RelativePath, StartupMode, StorageId, Url,
10};
11use cml_macro::CheckedVec;
12use serde::{Deserialize, Serialize};
13
14use std::fmt;
15
16#[derive(Deserialize, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
18#[serde(rename_all = "snake_case")]
19pub enum Right {
20 Connect,
22 Enumerate,
23 Execute,
24 GetAttributes,
25 ModifyDirectory,
26 ReadBytes,
27 Traverse,
28 UpdateAttributes,
29 WriteBytes,
30
31 #[serde(rename = "r*")]
33 ReadAlias,
34 #[serde(rename = "w*")]
35 WriteAlias,
36 #[serde(rename = "x*")]
37 ExecuteAlias,
38 #[serde(rename = "rw*")]
39 ReadWriteAlias,
40 #[serde(rename = "rx*")]
41 ReadExecuteAlias,
42}
43
44impl fmt::Display for Right {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 let s = match self {
47 Self::Connect => "connect",
48 Self::Enumerate => "enumerate",
49 Self::Execute => "execute",
50 Self::GetAttributes => "get_attributes",
51 Self::ModifyDirectory => "modify_directory",
52 Self::ReadBytes => "read_bytes",
53 Self::Traverse => "traverse",
54 Self::UpdateAttributes => "update_attributes",
55 Self::WriteBytes => "write_bytes",
56 Self::ReadAlias => "r*",
57 Self::WriteAlias => "w*",
58 Self::ExecuteAlias => "x*",
59 Self::ReadWriteAlias => "rw*",
60 Self::ReadExecuteAlias => "rx*",
61 };
62 write!(f, "{}", s)
63 }
64}
65
66impl Right {
67 pub fn expand(&self) -> Vec<fio::Operations> {
69 match self {
70 Self::Connect => vec![fio::Operations::CONNECT],
71 Self::Enumerate => vec![fio::Operations::ENUMERATE],
72 Self::Execute => vec![fio::Operations::EXECUTE],
73 Self::GetAttributes => vec![fio::Operations::GET_ATTRIBUTES],
74 Self::ModifyDirectory => vec![fio::Operations::MODIFY_DIRECTORY],
75 Self::ReadBytes => vec![fio::Operations::READ_BYTES],
76 Self::Traverse => vec![fio::Operations::TRAVERSE],
77 Self::UpdateAttributes => vec![fio::Operations::UPDATE_ATTRIBUTES],
78 Self::WriteBytes => vec![fio::Operations::WRITE_BYTES],
79 Self::ReadAlias => vec![
80 fio::Operations::CONNECT,
81 fio::Operations::ENUMERATE,
82 fio::Operations::TRAVERSE,
83 fio::Operations::READ_BYTES,
84 fio::Operations::GET_ATTRIBUTES,
85 ],
86 Self::WriteAlias => vec![
87 fio::Operations::CONNECT,
88 fio::Operations::ENUMERATE,
89 fio::Operations::TRAVERSE,
90 fio::Operations::WRITE_BYTES,
91 fio::Operations::MODIFY_DIRECTORY,
92 fio::Operations::UPDATE_ATTRIBUTES,
93 ],
94 Self::ExecuteAlias => vec![
95 fio::Operations::CONNECT,
96 fio::Operations::ENUMERATE,
97 fio::Operations::TRAVERSE,
98 fio::Operations::EXECUTE,
99 ],
100 Self::ReadWriteAlias => vec![
101 fio::Operations::CONNECT,
102 fio::Operations::ENUMERATE,
103 fio::Operations::TRAVERSE,
104 fio::Operations::READ_BYTES,
105 fio::Operations::WRITE_BYTES,
106 fio::Operations::MODIFY_DIRECTORY,
107 fio::Operations::GET_ATTRIBUTES,
108 fio::Operations::UPDATE_ATTRIBUTES,
109 ],
110 Self::ReadExecuteAlias => vec![
111 fio::Operations::CONNECT,
112 fio::Operations::ENUMERATE,
113 fio::Operations::TRAVERSE,
114 fio::Operations::READ_BYTES,
115 fio::Operations::GET_ATTRIBUTES,
116 fio::Operations::EXECUTE,
117 ],
118 }
119 }
120}
121
122#[derive(CheckedVec, Debug, PartialEq, Clone)]
124#[checked_vec(
125 expected = "a nonempty array of rights, with unique elements",
126 min_length = 1,
127 unique_items = true
128)]
129pub struct Rights(pub Vec<Right>);
130
131pub trait RightsClause {
132 fn rights(&self) -> Option<&Rights>;
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::types::right::Right;
138 use fidl_fuchsia_io as fio;
139
140 macro_rules! test_parse_rights {
141 (
142 $(
143 ($input:expr, $expected:expr),
144 )+
145 ) => {
146 #[test]
147 fn parse_rights() {
148 $(
149 parse_rights_test($input, $expected);
150 )+
151 }
152 }
153 }
154
155 fn parse_rights_test(input: &str, expected: Right) {
156 let r: Right = serde_json5::from_str(&format!("\"{}\"", input)).expect("invalid json");
157 assert_eq!(r, expected);
158 }
159
160 test_parse_rights! {
161 ("connect", Right::Connect),
162 ("enumerate", Right::Enumerate),
163 ("execute", Right::Execute),
164 ("get_attributes", Right::GetAttributes),
165 ("modify_directory", Right::ModifyDirectory),
166 ("read_bytes", Right::ReadBytes),
167 ("traverse", Right::Traverse),
168 ("update_attributes", Right::UpdateAttributes),
169 ("write_bytes", Right::WriteBytes),
170 ("r*", Right::ReadAlias),
171 ("w*", Right::WriteAlias),
172 ("x*", Right::ExecuteAlias),
173 ("rw*", Right::ReadWriteAlias),
174 ("rx*", Right::ReadExecuteAlias),
175 }
176
177 macro_rules! test_expand_rights {
178 (
179 $(
180 ($input:expr, $expected:expr),
181 )+
182 ) => {
183 #[test]
184 fn expand_rights() {
185 $(
186 expand_rights_test($input, $expected);
187 )+
188 }
189 }
190 }
191
192 fn expand_rights_test(input: Right, expected: Vec<fio::Operations>) {
193 assert_eq!(input.expand(), expected);
194 }
195
196 test_expand_rights! {
197 (Right::Connect, vec![fio::Operations::CONNECT]),
198 (Right::Enumerate, vec![fio::Operations::ENUMERATE]),
199 (Right::Execute, vec![fio::Operations::EXECUTE]),
200 (Right::GetAttributes, vec![fio::Operations::GET_ATTRIBUTES]),
201 (Right::ModifyDirectory, vec![fio::Operations::MODIFY_DIRECTORY]),
202 (Right::ReadBytes, vec![fio::Operations::READ_BYTES]),
203 (Right::Traverse, vec![fio::Operations::TRAVERSE]),
204 (Right::UpdateAttributes, vec![fio::Operations::UPDATE_ATTRIBUTES]),
205 (Right::WriteBytes, vec![fio::Operations::WRITE_BYTES]),
206 (Right::ReadAlias, vec![
207 fio::Operations::CONNECT,
208 fio::Operations::ENUMERATE,
209 fio::Operations::TRAVERSE,
210 fio::Operations::READ_BYTES,
211 fio::Operations::GET_ATTRIBUTES,
212 ]),
213 (Right::WriteAlias, vec![
214 fio::Operations::CONNECT,
215 fio::Operations::ENUMERATE,
216 fio::Operations::TRAVERSE,
217 fio::Operations::WRITE_BYTES,
218 fio::Operations::MODIFY_DIRECTORY,
219 fio::Operations::UPDATE_ATTRIBUTES,
220 ]),
221 (Right::ExecuteAlias, vec![
222 fio::Operations::CONNECT,
223 fio::Operations::ENUMERATE,
224 fio::Operations::TRAVERSE,
225 fio::Operations::EXECUTE,
226 ]),
227 (Right::ReadWriteAlias, vec![
228 fio::Operations::CONNECT,
229 fio::Operations::ENUMERATE,
230 fio::Operations::TRAVERSE,
231 fio::Operations::READ_BYTES,
232 fio::Operations::WRITE_BYTES,
233 fio::Operations::MODIFY_DIRECTORY,
234 fio::Operations::GET_ATTRIBUTES,
235 fio::Operations::UPDATE_ATTRIBUTES,
236 ]),
237 (Right::ReadExecuteAlias, vec![
238 fio::Operations::CONNECT,
239 fio::Operations::ENUMERATE,
240 fio::Operations::TRAVERSE,
241 fio::Operations::READ_BYTES,
242 fio::Operations::GET_ATTRIBUTES,
243 fio::Operations::EXECUTE,
244 ]),
245 }
246}