atspi_common/
object_ref.rs
1use serde::{Deserialize, Serialize};
2use zbus_lockstep_macros::validate;
3use zbus_names::{OwnedUniqueName, UniqueName};
4use zvariant::{ObjectPath, OwnedObjectPath, Signature, Type};
5
6pub const OBJECT_REF_SIGNATURE: Signature<'_> = Signature::from_static_str_unchecked("(so)");
7
8#[validate(signal: "Available")]
17#[derive(Debug, Clone, Serialize, Deserialize, Type, PartialEq, Eq, Hash)]
18pub struct ObjectRef {
19 pub name: OwnedUniqueName,
20 pub path: OwnedObjectPath,
21}
22
23impl Default for ObjectRef {
24 fn default() -> Self {
25 ObjectRef {
26 name: UniqueName::from_static_str(":0.0").unwrap().into(),
27 path: ObjectPath::from_static_str("/org/a11y/atspi/accessible/null")
28 .unwrap()
29 .into(),
30 }
31 }
32}
33
34#[cfg(test)]
35#[test]
36fn test_accessible_from_dbus_ctxt_to_accessible() {
37 use zvariant::serialized::Context;
38 use zvariant::{to_bytes, Value, LE};
39
40 let acc = ObjectRef::default();
41 let ctxt = Context::new_dbus(LE, 0);
42 let acc_value: Value<'_> = acc.into();
43 let data = to_bytes(ctxt, &acc_value).unwrap();
44 let (value, _) = data.deserialize::<Value>().unwrap();
45 let accessible: ObjectRef = value.try_into().unwrap();
46
47 assert_eq!(accessible.name.as_str(), ":0.0");
48 assert_eq!(accessible.path.as_str(), "/org/a11y/atspi/accessible/null");
49}
50
51#[cfg(test)]
52#[test]
53fn test_accessible_value_wrapped_from_dbus_ctxt_to_accessible() {
54 use zvariant::serialized::Context;
55 use zvariant::{to_bytes, Value, LE};
56
57 let acc = ObjectRef::default();
58 let value: zvariant::Value = acc.into();
59 let ctxt = Context::new_dbus(LE, 0);
60 let encoded = to_bytes(ctxt, &value).unwrap();
61 let (value, _) = encoded.deserialize::<Value>().unwrap();
62 let accessible: ObjectRef = value.try_into().unwrap();
63
64 assert_eq!(accessible.name.as_str(), ":0.0");
65 assert_eq!(accessible.path.as_str(), "/org/a11y/atspi/accessible/null");
66}
67
68impl<'a> TryFrom<zvariant::Value<'a>> for ObjectRef {
69 type Error = zvariant::Error;
70 fn try_from(value: zvariant::Value<'a>) -> Result<Self, Self::Error> {
71 value.try_to_owned()?.try_into()
72 }
73}
74
75impl TryFrom<zvariant::OwnedValue> for ObjectRef {
76 type Error = zvariant::Error;
77 fn try_from<'a>(value: zvariant::OwnedValue) -> Result<Self, Self::Error> {
78 match &*value {
79 zvariant::Value::Structure(s) => {
80 if s.signature() != OBJECT_REF_SIGNATURE {
81 return Err(zvariant::Error::SignatureMismatch(s.signature(), format!("To turn a zvariant::Value into an atspi::ObjectRef, it must be of type {}", OBJECT_REF_SIGNATURE.as_str())));
82 }
83 let fields = s.fields();
84 let name: String =
85 fields.first().ok_or(zvariant::Error::IncorrectType)?.try_into()?;
86 let path_value: ObjectPath<'_> =
87 fields.last().ok_or(zvariant::Error::IncorrectType)?.try_into()?;
88 Ok(ObjectRef {
89 name: name.try_into().map_err(|_| zvariant::Error::IncorrectType)?,
90 path: path_value.into(),
91 })
92 }
93 _ => Err(zvariant::Error::IncorrectType),
94 }
95 }
96}
97
98impl From<ObjectRef> for zvariant::Structure<'_> {
99 fn from(obj: ObjectRef) -> Self {
100 (obj.name, obj.path).into()
101 }
102}