io_conformance_util/
flags.rs1use fidl_fuchsia_io as fio;
6
7pub struct Rights {
10 rights: fio::Rights,
11}
12
13impl Rights {
14 pub fn new(rights: fio::Rights) -> Rights {
16 Rights { rights }
17 }
18
19 pub fn all_rights(&self) -> fio::Rights {
21 self.rights
22 }
23
24 pub fn all_flags(&self) -> fio::Flags {
26 fio::Flags::from_bits_truncate(self.rights.bits())
28 }
29
30 pub fn all_flags_deprecated(&self) -> fio::OpenFlags {
32 let mut flags = fio::OpenFlags::empty();
33 if self.rights.contains(fio::Rights::READ_BYTES) {
34 flags |= fio::OpenFlags::RIGHT_READABLE;
35 }
36 if self.rights.contains(fio::Rights::WRITE_BYTES) {
37 flags |= fio::OpenFlags::RIGHT_WRITABLE;
38 }
39 if self.rights.contains(fio::Rights::EXECUTE) {
40 flags |= fio::OpenFlags::RIGHT_EXECUTABLE;
41 }
42 flags
43 }
44
45 pub fn rights_combinations(&self) -> Vec<fio::Rights> {
47 vfs::test_utils::build_flag_combinations(fio::Rights::empty(), self.rights)
48 }
49
50 pub fn combinations(&self) -> Vec<fio::Flags> {
52 vfs::test_utils::build_flag_combinations(fio::Flags::empty(), self.all_flags())
53 }
54
55 pub fn combinations_deprecated(&self) -> Vec<fio::OpenFlags> {
57 vfs::test_utils::build_flag_combinations(
58 fio::OpenFlags::empty(),
59 self.all_flags_deprecated(),
60 )
61 }
62
63 fn rights_combinations_containing(&self, with_rights: fio::Rights) -> Vec<fio::Rights> {
65 let mut right_combinations = self.rights_combinations();
66 right_combinations.retain(|&flags| flags.contains(with_rights));
67 right_combinations
68 }
69
70 pub fn combinations_containing(&self, with_rights: fio::Rights) -> Vec<fio::Flags> {
73 self.rights_combinations_containing(with_rights)
74 .into_iter()
75 .map(|combination| fio::Flags::from_bits_truncate(combination.bits()))
76 .collect()
77 }
78
79 pub fn combinations_containing_deprecated(
82 &self,
83 with_rights: fio::Rights,
84 ) -> Vec<fio::OpenFlags> {
85 self.rights_combinations_containing(with_rights)
86 .into_iter()
87 .map(|combination| {
88 let mut flags = fio::OpenFlags::empty();
89 if combination.contains(fio::Rights::READ_BYTES) {
90 flags |= fio::OpenFlags::RIGHT_READABLE;
91 }
92 if combination.contains(fio::Rights::WRITE_BYTES) {
93 flags |= fio::OpenFlags::RIGHT_WRITABLE;
94 }
95 if combination.contains(fio::Rights::EXECUTE) {
96 flags |= fio::OpenFlags::RIGHT_EXECUTABLE;
97 }
98 flags
99 })
100 .collect()
101 }
102
103 fn combinations_without_as_rights(&self, without_rights: fio::Rights) -> Vec<fio::Rights> {
105 let mut right_combinations = self.rights_combinations();
106 right_combinations.retain(|&flags| !flags.intersects(without_rights));
107 right_combinations
108 }
109
110 pub fn combinations_without(&self, without_rights: fio::Rights) -> Vec<fio::Flags> {
113 self.combinations_without_as_rights(without_rights)
114 .into_iter()
115 .map(|combination| fio::Flags::from_bits_truncate(combination.bits()))
116 .collect()
117 }
118
119 pub fn combinations_without_deprecated(
122 &self,
123 without_rights: fio::Rights,
124 ) -> Vec<fio::OpenFlags> {
125 self.combinations_without_as_rights(without_rights)
126 .into_iter()
127 .map(|combination| {
128 let mut flags = fio::OpenFlags::empty();
129 if combination.contains(fio::Rights::READ_BYTES) {
130 flags |= fio::OpenFlags::RIGHT_READABLE;
131 }
132 if combination.contains(fio::Rights::WRITE_BYTES) {
133 flags |= fio::OpenFlags::RIGHT_WRITABLE;
134 }
135 if combination.contains(fio::Rights::EXECUTE) {
136 flags |= fio::OpenFlags::RIGHT_EXECUTABLE;
137 }
138 flags
139 })
140 .collect()
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_rights_combinations_flags_deprecated() {
150 const TEST_RIGHTS: fio::Rights = fio::Rights::empty()
151 .union(fio::Rights::READ_BYTES)
152 .union(fio::Rights::WRITE_BYTES)
153 .union(fio::Rights::EXECUTE);
154
155 const EXPECTED_COMBINATIONS: [fio::OpenFlags; 8] = [
157 fio::OpenFlags::empty(),
158 fio::OpenFlags::RIGHT_READABLE,
159 fio::OpenFlags::RIGHT_WRITABLE,
160 fio::OpenFlags::RIGHT_EXECUTABLE,
161 fio::OpenFlags::empty()
162 .union(fio::OpenFlags::RIGHT_READABLE)
163 .union(fio::OpenFlags::RIGHT_WRITABLE),
164 fio::OpenFlags::empty()
165 .union(fio::OpenFlags::RIGHT_READABLE)
166 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
167 fio::OpenFlags::empty()
168 .union(fio::OpenFlags::RIGHT_WRITABLE)
169 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
170 fio::OpenFlags::empty()
171 .union(fio::OpenFlags::RIGHT_READABLE)
172 .union(fio::OpenFlags::RIGHT_WRITABLE)
173 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
174 ];
175
176 let rights = Rights::new(TEST_RIGHTS);
178 assert_eq!(
179 rights.all_flags_deprecated(),
180 fio::OpenFlags::RIGHT_READABLE
181 | fio::OpenFlags::RIGHT_WRITABLE
182 | fio::OpenFlags::RIGHT_EXECUTABLE
183 );
184
185 let all_combinations = rights.combinations_deprecated();
187 assert_eq!(all_combinations.len(), EXPECTED_COMBINATIONS.len());
188 for expected_rights in EXPECTED_COMBINATIONS {
189 assert!(all_combinations.contains(&expected_rights));
190 }
191
192 const EXPECTED_READABLE_COMBOS: [fio::OpenFlags; 4] = [
195 fio::OpenFlags::RIGHT_READABLE,
196 fio::OpenFlags::empty()
197 .union(fio::OpenFlags::RIGHT_READABLE)
198 .union(fio::OpenFlags::RIGHT_WRITABLE),
199 fio::OpenFlags::empty()
200 .union(fio::OpenFlags::RIGHT_READABLE)
201 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
202 fio::OpenFlags::empty()
203 .union(fio::OpenFlags::RIGHT_READABLE)
204 .union(fio::OpenFlags::RIGHT_WRITABLE)
205 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
206 ];
207 let readable_combos = rights.combinations_containing_deprecated(fio::Rights::READ_BYTES);
208 assert_eq!(readable_combos.len(), EXPECTED_READABLE_COMBOS.len());
209 for expected_rights in EXPECTED_READABLE_COMBOS {
210 assert!(readable_combos.contains(&expected_rights));
211 }
212
213 const EXPECTED_NONREADABLE_COMBOS: [fio::OpenFlags; 4] = [
216 fio::OpenFlags::empty(),
217 fio::OpenFlags::RIGHT_WRITABLE,
218 fio::OpenFlags::RIGHT_EXECUTABLE,
219 fio::OpenFlags::empty()
220 .union(fio::OpenFlags::RIGHT_WRITABLE)
221 .union(fio::OpenFlags::RIGHT_EXECUTABLE),
222 ];
223 let nonreadable_combos = rights.combinations_without_deprecated(fio::Rights::READ_BYTES);
224 assert_eq!(nonreadable_combos.len(), EXPECTED_NONREADABLE_COMBOS.len());
225 for expected_rights in EXPECTED_NONREADABLE_COMBOS {
226 assert!(nonreadable_combos.contains(&expected_rights));
227 }
228 }
229
230 #[test]
231 fn test_rights_combinations_flags() {
232 const TEST_RIGHTS: fio::Rights = fio::Rights::empty()
233 .union(fio::Rights::READ_BYTES)
234 .union(fio::Rights::WRITE_BYTES)
235 .union(fio::Rights::EXECUTE);
236
237 const EXPECTED_COMBINATIONS: [fio::Flags; 8] = [
239 fio::Flags::empty(),
240 fio::Flags::PERM_READ,
241 fio::Flags::PERM_WRITE,
242 fio::Flags::PERM_EXECUTE,
243 fio::Flags::empty().union(fio::Flags::PERM_READ).union(fio::Flags::PERM_WRITE),
244 fio::Flags::empty().union(fio::Flags::PERM_READ).union(fio::Flags::PERM_EXECUTE),
245 fio::Flags::empty().union(fio::Flags::PERM_WRITE).union(fio::Flags::PERM_EXECUTE),
246 fio::Flags::empty()
247 .union(fio::Flags::PERM_READ)
248 .union(fio::Flags::PERM_WRITE)
249 .union(fio::Flags::PERM_EXECUTE),
250 ];
251
252 let rights = Rights::new(TEST_RIGHTS);
254 assert_eq!(
255 rights.all_flags(),
256 fio::Flags::PERM_READ | fio::Flags::PERM_WRITE | fio::Flags::PERM_EXECUTE
257 );
258
259 let all_combinations = rights.combinations();
261 assert_eq!(all_combinations.len(), EXPECTED_COMBINATIONS.len());
262 for expected_rights in EXPECTED_COMBINATIONS {
263 assert!(all_combinations.contains(&expected_rights));
264 }
265
266 const EXPECTED_READABLE_COMBOS: [fio::Flags; 4] = [
269 fio::Flags::PERM_READ,
270 fio::Flags::empty().union(fio::Flags::PERM_READ).union(fio::Flags::PERM_WRITE),
271 fio::Flags::empty().union(fio::Flags::PERM_READ).union(fio::Flags::PERM_EXECUTE),
272 fio::Flags::empty()
273 .union(fio::Flags::PERM_READ)
274 .union(fio::Flags::PERM_WRITE)
275 .union(fio::Flags::PERM_EXECUTE),
276 ];
277 let readable_combos = rights.combinations_containing(fio::Rights::READ_BYTES);
278 assert_eq!(readable_combos.len(), EXPECTED_READABLE_COMBOS.len());
279 for expected_rights in EXPECTED_READABLE_COMBOS {
280 assert!(readable_combos.contains(&expected_rights));
281 }
282
283 const EXPECTED_NONREADABLE_COMBOS: [fio::Flags; 4] = [
286 fio::Flags::empty(),
287 fio::Flags::PERM_WRITE,
288 fio::Flags::PERM_EXECUTE,
289 fio::Flags::empty().union(fio::Flags::PERM_WRITE).union(fio::Flags::PERM_EXECUTE),
290 ];
291 let nonreadable_combos = rights.combinations_without(fio::Rights::READ_BYTES);
292 assert_eq!(nonreadable_combos.len(), EXPECTED_NONREADABLE_COMBOS.len());
293 for expected_rights in EXPECTED_NONREADABLE_COMBOS {
294 assert!(nonreadable_combos.contains(&expected_rights));
295 }
296 }
297}