1use crate::events::signatures_are_eq;
2use serde::{Deserialize, Serialize};
3use zvariant::{ObjectPath, OwnedObjectPath, Signature, Type};
4
5pub const ACCESSIBLE_PAIR_SIGNATURE: Signature<'_> = Signature::from_static_str_unchecked(signature:"(so)");
6
7// TODO: Try to make borrowed versions work,
8// check where the lifetimes of the borrow are tied to, see also: comment on `interface()` method
9// in `DefaultEvent` impl
10// then rename into Owned for this one.
11/// Owned Accessible type
12/// Emitted by `CacheRemove` and `Available`
13#[derive(Debug, Clone, Serialize, Deserialize, Type, PartialEq, Eq, Hash)]
14pub struct Accessible {
15 pub name: String,
16 pub path: OwnedObjectPath,
17}
18
19impl Default for Accessible {
20 fn default() -> Self {
21 Accessible {
22 name: ":0.0".into(),
23 path: ObjectPathObjectPath<'_>::from_static_str(name:"/org/a11y/atspi/accessible/null")
24 .unwrap()
25 .into(),
26 }
27 }
28}
29
30#[test]
31fn test_accessible_signature() {
32 assert_eq!(
33 Accessible::signature(),
34 ACCESSIBLE_PAIR_SIGNATURE,
35 "Accessible does not have the correct type."
36 );
37}
38
39#[test]
40fn test_accessible_from_dbus_ctxt_to_accessible() {
41 use zvariant::{from_slice, to_bytes, EncodingContext as Context, Value};
42
43 let acc: Accessible = Accessible::default();
44 let ctxt: EncodingContext<{unknown}> = Context::<byteorder::LE>::new_dbus(position:0);
45 let acc_value: Value<'_> = acc.try_into().unwrap();
46 let encoded: Vec = to_bytes(ctxt, &acc_value).unwrap();
47 let decoded: Value = from_slice(&encoded, ctxt).unwrap();
48 let accessible: Accessible = decoded.try_into().unwrap();
49
50 assert_eq!(accessible.name.as_str(), ":0.0");
51 assert_eq!(accessible.path.as_str(), "/org/a11y/atspi/accessible/null");
52}
53
54#[test]
55fn test_accessible_value_wrapped_from_dbus_ctxt_to_accessible() {
56 use zvariant::{from_slice, to_bytes, EncodingContext as Context, Value};
57
58 let acc: Accessible = Accessible::default();
59 let value: zvariant::Value = acc.into();
60 let ctxt: EncodingContext<{unknown}> = Context::<byteorder::LE>::new_dbus(position:0);
61 let encoded: Vec = to_bytes(ctxt, &value).unwrap();
62 let decoded: Value = from_slice(&encoded, ctxt).unwrap();
63 let accessible: Accessible = decoded.try_into().unwrap();
64
65 assert_eq!(accessible.name.as_str(), ":0.0");
66 assert_eq!(accessible.path.as_str(), "/org/a11y/atspi/accessible/null");
67}
68
69impl<'a> TryFrom<zvariant::Value<'a>> for Accessible {
70 type Error = zvariant::Error;
71 fn try_from(value: zvariant::Value<'a>) -> Result<Self, Self::Error> {
72 value.to_owned().try_into()
73 }
74}
75
76impl TryFrom<zvariant::OwnedValue> for Accessible {
77 type Error = zvariant::Error;
78 fn try_from<'a>(value: zvariant::OwnedValue) -> Result<Self, Self::Error> {
79 match &*value {
80 zvariant::Value::Structure(s: &Structure<'_>) => {
81 if !signatures_are_eq(&s.signature(), &ACCESSIBLE_PAIR_SIGNATURE) {
82 return Err(zvariant::Error::SignatureMismatch(s.signature(), format!("To turn a zvariant::Value into an atspi::Accessible, it must be of type {}", ACCESSIBLE_PAIR_SIGNATURE.as_str())));
83 }
84 let fields: &[Value<'_>] = s.fields();
85 let name: String =
86 fields.get(0).ok_or(err:zvariant::Error::IncorrectType)?.try_into()?;
87 let path_value: ObjectPath<'_> =
88 fields.get(1).ok_or(err:zvariant::Error::IncorrectType)?.try_into()?;
89 Ok(Accessible { name, path: path_value.into() })
90 }
91 _ => Err(zvariant::Error::IncorrectType),
92 }
93 }
94}
95
96impl From<Accessible> for zvariant::Structure<'_> {
97 fn from(accessible: Accessible) -> Self {
98 (accessible.name.as_str().to_string(), accessible.path).into()
99 }
100}
101