1use enumflags2::{bitflags, BitFlag, BitFlags};
7use serde::{
8 de::{self, Deserializer, Visitor},
9 ser::{self, Serializer},
10 Deserialize, Serialize,
11};
12use std::fmt;
13use zvariant::{Signature, Type};
14
15#[bitflags]
17#[repr(u32)]
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
19pub enum Interface {
20 #[serde(rename = "org.a11y.atspi.Accessible")]
22 Accessible,
23 #[serde(rename = "org.a11y.atspi.Action")]
25 Action,
26 #[serde(rename = "org.a11y.atspi.Application")]
28 Application,
29 #[serde(rename = "org.a11y.atspi.Cache")]
31 Cache,
32 #[serde(rename = "org.a11y.atspi.Collection")]
34 Collection,
35 #[serde(rename = "org.a11y.atspi.Component")]
37 Component,
38 #[serde(rename = "org.a11y.atspi.Document")]
40 Document,
41 #[serde(rename = "org.a11y.atspi.DeviceEventController")]
43 DeviceEventController,
44 #[serde(rename = "org.a11y.atspi.DeviceEventListener")]
46 DeviceEventListener,
47 #[serde(rename = "org.a11y.atspi.EditableText")]
49 EditableText,
50 #[serde(rename = "org.a11y.atspi.Hyperlink")]
52 Hyperlink,
53 #[serde(rename = "org.a11y.atspi.Hypertext")]
55 Hypertext,
56 #[serde(rename = "org.a11y.atspi.Image")]
58 Image,
59 #[serde(rename = "org.a11y.atspi.Registry")]
61 Registry,
62 #[serde(rename = "org.a11y.atspi.Selection")]
64 Selection,
65 #[serde(rename = "org.a11y.atspi.Socket")]
67 Socket,
68 #[serde(rename = "org.a11y.atspi.Table")]
70 Table,
71 #[serde(rename = "org.a11y.atspi.TableCell")]
73 TableCell,
74 #[serde(rename = "org.a11y.atspi.Text")]
76 Text,
77 #[serde(rename = "org.a11y.atspi.Value")]
79 Value,
80}
81
82#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
84pub struct InterfaceSet(BitFlags<Interface>);
85
86impl InterfaceSet {
87 pub fn new<B: Into<BitFlags<Interface>>>(value: B) -> Self {
88 Self(value.into())
89 }
90
91 #[must_use]
92 pub fn empty() -> InterfaceSet {
93 InterfaceSet(Interface::empty())
94 }
95
96 #[must_use]
97 pub fn bits(&self) -> u32 {
98 self.0.bits()
99 }
100
101 #[must_use]
102 pub fn all() -> InterfaceSet {
103 InterfaceSet(Interface::all())
104 }
105
106 pub fn contains<B: Into<BitFlags<Interface>>>(self, other: B) -> bool {
107 self.0.contains(other)
108 }
109
110 pub fn insert<B: Into<BitFlags<Interface>>>(&mut self, other: B) {
111 self.0.insert(other);
112 }
113
114 #[must_use]
115 pub fn iter(&self) -> enumflags2::Iter<Interface> {
116 self.0.iter()
117 }
118}
119
120impl IntoIterator for InterfaceSet {
121 type IntoIter = enumflags2::Iter<Interface>;
122 type Item = Interface;
123
124 fn into_iter(self) -> Self::IntoIter {
125 self.iter()
126 }
127}
128
129impl IntoIterator for &InterfaceSet {
130 type IntoIter = enumflags2::Iter<Interface>;
131 type Item = Interface;
132
133 fn into_iter(self) -> Self::IntoIter {
134 self.iter()
135 }
136}
137
138impl Default for InterfaceSet {
139 fn default() -> Self {
140 Self::empty()
141 }
142}
143
144impl<'de> de::Deserialize<'de> for InterfaceSet {
145 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
146 where
147 D: Deserializer<'de>,
148 {
149 struct InterfaceSetVisitor;
150
151 impl<'de> Visitor<'de> for InterfaceSetVisitor {
152 type Value = InterfaceSet;
153
154 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
155 formatter.write_str("a sequence comprised of valid AT-SPI interface names")
156 }
157
158 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
159 where
160 D: Deserializer<'de>,
161 {
162 match <Vec<Interface> as Deserialize>::deserialize(deserializer) {
163 Ok(interfaces) => Ok(InterfaceSet(BitFlags::from_iter(interfaces))),
164 Err(e) => Err(e),
165 }
166 }
167 }
168
169 deserializer.deserialize_newtype_struct("InterfaceSet", InterfaceSetVisitor)
170 }
171}
172
173impl ser::Serialize for InterfaceSet {
174 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175 where
176 S: Serializer,
177 {
178 serializer
179 .serialize_newtype_struct("InterfaceSet", &self.0.iter().collect::<Vec<Interface>>())
180 }
181}
182
183impl Type for InterfaceSet {
184 const SIGNATURE: &'static Signature = <Vec<String> as Type>::SIGNATURE;
185}
186
187impl FromIterator<Interface> for InterfaceSet {
188 fn from_iter<T: IntoIterator<Item = Interface>>(iter: T) -> Self {
189 Self(BitFlags::from_iter(iter))
190 }
191}
192
193impl<'a> FromIterator<&'a Interface> for InterfaceSet {
194 fn from_iter<I: IntoIterator<Item = &'a Interface>>(iter: I) -> Self {
195 InterfaceSet(iter.into_iter().copied().collect())
196 }
197}
198
199impl From<Interface> for InterfaceSet {
200 fn from(value: Interface) -> Self {
201 Self(value.into())
202 }
203}
204
205impl std::ops::BitAnd for InterfaceSet {
206 type Output = InterfaceSet;
207
208 fn bitand(self, other: Self) -> Self::Output {
209 InterfaceSet(self.0 & other.0)
210 }
211}
212
213impl std::ops::BitXor for InterfaceSet {
214 type Output = InterfaceSet;
215
216 fn bitxor(self, other: Self) -> Self::Output {
217 InterfaceSet(self.0 ^ other.0)
218 }
219}
220
221impl std::ops::BitOr for InterfaceSet {
222 type Output = InterfaceSet;
223
224 fn bitor(self, other: Self) -> Self::Output {
225 InterfaceSet(self.0 | other.0)
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::{Interface, InterfaceSet};
232 use zvariant::serialized::Data;
233 use zvariant::{serialized::Context, to_bytes, LE};
234
235 #[test]
236 fn serialize_empty_interface_set() {
237 let ctxt = Context::new_dbus(LE, 0);
238 let encoded = to_bytes(ctxt, &InterfaceSet::empty()).unwrap();
239 assert_eq!(encoded.bytes(), &[0, 0, 0, 0]);
240 }
241
242 #[test]
243 fn deserialize_empty_interface_set() {
244 let ctxt = Context::new_dbus(LE, 0);
245 let encoded = to_bytes(ctxt, &InterfaceSet::empty()).unwrap();
246 let (decoded, _) = encoded.deserialize::<InterfaceSet>().unwrap();
247 assert_eq!(decoded, InterfaceSet::empty());
248 }
249
250 #[test]
251 fn serialize_interface_set_accessible() {
252 let ctxt = Context::new_dbus(LE, 0);
253 let encoded = to_bytes(ctxt, &InterfaceSet::new(Interface::Accessible)).unwrap();
254 assert_eq!(
255 encoded.bytes(),
256 &[
257 30, 0, 0, 0, 25, 0, 0, 0, 111, 114, 103, 46, 97, 49, 49, 121, 46, 97, 116, 115,
258 112, 105, 46, 65, 99, 99, 101, 115, 115, 105, 98, 108, 101, 0
259 ]
260 );
261 }
262
263 #[test]
264 fn deserialize_interface_set_accessible() {
265 let ctxt = Context::new_dbus(LE, 0);
266 let data = Data::new::<&[u8]>(
267 &[
268 30, 0, 0, 0, 25, 0, 0, 0, 111, 114, 103, 46, 97, 49, 49, 121, 46, 97, 116, 115,
269 112, 105, 46, 65, 99, 99, 101, 115, 115, 105, 98, 108, 101, 0,
270 ],
271 ctxt,
272 );
273
274 let (ifaceset, _) = data.deserialize::<InterfaceSet>().unwrap();
275 assert_eq!(ifaceset, InterfaceSet::new(Interface::Accessible));
276 }
277
278 #[test]
279 fn can_handle_multiple_interfaces() {
280 let ctxt = Context::new_dbus(LE, 0);
281 let object =
282 InterfaceSet::new(Interface::Accessible | Interface::Action | Interface::Component);
283 let encoded = to_bytes(ctxt, &object).unwrap();
284 let (decoded, _) = encoded.deserialize::<InterfaceSet>().unwrap();
285 assert!(object == decoded);
286 }
287
288 #[test]
290 fn iterator_on_interface_set() {
291 let set =
292 InterfaceSet::new(Interface::Accessible | Interface::Action | Interface::Component);
293 let mut iter = set.into_iter();
294 assert_eq!(iter.next(), Some(Interface::Accessible));
295 assert_eq!(iter.next(), Some(Interface::Action));
296 assert_eq!(iter.next(), Some(Interface::Component));
297 assert_eq!(iter.next(), None);
298 }
299
300 #[test]
301 fn iterator_on_interface_set_ref() {
302 let set = InterfaceSet::new(Interface::Text | Interface::Collection | Interface::Component);
303 let mut iter = (&set).into_iter();
304 assert_eq!(iter.next(), Some(Interface::Collection));
305 assert_eq!(iter.next(), Some(Interface::Component));
306 assert_eq!(iter.next(), Some(Interface::Text));
307 }
308}