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 rights_combinations(&self) -> Vec<fio::Rights> {
32 build_flag_combinations(fio::Rights::empty(), self.rights)
33 }
34
35 pub fn combinations(&self) -> Vec<fio::Flags> {
37 build_flag_combinations(fio::Flags::empty(), self.all_flags())
38 }
39
40 fn rights_combinations_containing(&self, with_rights: fio::Rights) -> Vec<fio::Rights> {
42 let mut right_combinations = self.rights_combinations();
43 right_combinations.retain(|&flags| flags.contains(with_rights));
44 right_combinations
45 }
46
47 pub fn combinations_containing(&self, with_rights: fio::Rights) -> Vec<fio::Flags> {
50 self.rights_combinations_containing(with_rights)
51 .into_iter()
52 .map(|combination| fio::Flags::from_bits_truncate(combination.bits()))
53 .collect()
54 }
55
56 fn combinations_without_as_rights(&self, without_rights: fio::Rights) -> Vec<fio::Rights> {
58 let mut right_combinations = self.rights_combinations();
59 right_combinations.retain(|&flags| !flags.intersects(without_rights));
60 right_combinations
61 }
62
63 pub fn combinations_without(&self, without_rights: fio::Rights) -> Vec<fio::Flags> {
66 self.combinations_without_as_rights(without_rights)
67 .into_iter()
68 .map(|combination| fio::Flags::from_bits_truncate(combination.bits()))
69 .collect()
70 }
71}
72
73pub fn build_flag_combinations<T: bitflags::Flags + Copy>(
78 constant_flags: T,
79 variable_flags: T,
80) -> Vec<T> {
81 let mut vec = vec![constant_flags];
82 for flag in variable_flags.iter() {
83 for i in 0..vec.len() {
84 vec.push(vec[i].union(flag));
85 }
86 }
87 vec
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_rights_combinations_flags() {
96 const TEST_RIGHTS: fio::Rights = fio::Rights::empty()
97 .union(fio::Rights::READ_BYTES)
98 .union(fio::Rights::WRITE_BYTES)
99 .union(fio::Rights::EXECUTE);
100
101 const EXPECTED_COMBINATIONS: [fio::Flags; 8] = [
103 fio::Flags::empty(),
104 fio::Flags::PERM_READ_BYTES,
105 fio::Flags::PERM_WRITE_BYTES,
106 fio::Flags::PERM_EXECUTE,
107 fio::Flags::empty()
108 .union(fio::Flags::PERM_READ_BYTES)
109 .union(fio::Flags::PERM_WRITE_BYTES),
110 fio::Flags::empty().union(fio::Flags::PERM_READ_BYTES).union(fio::Flags::PERM_EXECUTE),
111 fio::Flags::empty().union(fio::Flags::PERM_WRITE_BYTES).union(fio::Flags::PERM_EXECUTE),
112 fio::Flags::empty()
113 .union(fio::Flags::PERM_READ_BYTES)
114 .union(fio::Flags::PERM_WRITE_BYTES)
115 .union(fio::Flags::PERM_EXECUTE),
116 ];
117
118 let rights = Rights::new(TEST_RIGHTS);
120 assert_eq!(
121 rights.all_flags(),
122 fio::Flags::PERM_READ_BYTES | fio::Flags::PERM_WRITE_BYTES | fio::Flags::PERM_EXECUTE
123 );
124
125 let all_combinations = rights.combinations();
127 assert_eq!(all_combinations.len(), EXPECTED_COMBINATIONS.len());
128 for expected_rights in EXPECTED_COMBINATIONS {
129 assert!(all_combinations.contains(&expected_rights));
130 }
131
132 const EXPECTED_READABLE_COMBOS: [fio::Flags; 4] = [
135 fio::Flags::PERM_READ_BYTES,
136 fio::Flags::empty()
137 .union(fio::Flags::PERM_READ_BYTES)
138 .union(fio::Flags::PERM_WRITE_BYTES),
139 fio::Flags::empty().union(fio::Flags::PERM_READ_BYTES).union(fio::Flags::PERM_EXECUTE),
140 fio::Flags::empty()
141 .union(fio::Flags::PERM_READ_BYTES)
142 .union(fio::Flags::PERM_WRITE_BYTES)
143 .union(fio::Flags::PERM_EXECUTE),
144 ];
145 let readable_combos = rights.combinations_containing(fio::Rights::READ_BYTES);
146 assert_eq!(readable_combos.len(), EXPECTED_READABLE_COMBOS.len());
147 for expected_rights in EXPECTED_READABLE_COMBOS {
148 assert!(readable_combos.contains(&expected_rights));
149 }
150
151 const EXPECTED_NONREADABLE_COMBOS: [fio::Flags; 4] = [
154 fio::Flags::empty(),
155 fio::Flags::PERM_WRITE_BYTES,
156 fio::Flags::PERM_EXECUTE,
157 fio::Flags::empty().union(fio::Flags::PERM_WRITE_BYTES).union(fio::Flags::PERM_EXECUTE),
158 ];
159 let nonreadable_combos = rights.combinations_without(fio::Rights::READ_BYTES);
160 assert_eq!(nonreadable_combos.len(), EXPECTED_NONREADABLE_COMBOS.len());
161 for expected_rights in EXPECTED_NONREADABLE_COMBOS {
162 assert!(nonreadable_combos.contains(&expected_rights));
163 }
164 }
165}