1use crate::AtspiError;
2use serde::{
3 ser::{SerializeMap, SerializeTuple},
4 Deserialize, Serialize,
5};
6use zbus_lockstep_macros::validate;
7use zvariant::{ObjectPath, OwnedValue, Type, Value};
8
9#[derive(Debug, Serialize, Deserialize, PartialEq, Type)]
13pub struct EventBodyQtOwned {
14 #[serde(rename = "type")]
17 pub kind: String,
18
19 pub detail1: i32,
21
22 pub detail2: i32,
24
25 pub any_data: OwnedValue,
28
29 #[serde(skip_deserializing)]
32 pub(crate) properties: QtProperties,
33}
34
35impl Clone for EventBodyQtOwned {
36 fn clone(&self) -> Self {
50 let cloned_any_data = self.any_data.try_clone().unwrap_or_else(|err| {
51 panic!("Failure cloning 'any_data' field: {err:?}");
52 });
53
54 Self {
55 kind: self.kind.clone(),
56 detail1: self.detail1,
57 detail2: self.detail2,
58 any_data: cloned_any_data,
59 properties: QtProperties,
60 }
61 }
62}
63
64#[derive(Debug, Copy, Clone, Deserialize, Type, Default, PartialEq)]
70#[zvariant(signature = "(so)")]
71pub(crate) struct QtProperties;
72
73impl Serialize for QtProperties {
74 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75 where
76 S: serde::ser::Serializer,
77 {
78 let mut tup = serializer.serialize_tuple(2)?;
79 tup.serialize_element(":0.0")?;
80 tup.serialize_element(&ObjectPath::from_static_str_unchecked("/"))?;
81 tup.end()
82 }
83}
84
85impl Default for EventBodyQtOwned {
86 fn default() -> Self {
87 Self {
88 kind: String::new(),
89 detail1: 0,
90 detail2: 0,
91 any_data: 0_u32.into(),
92 properties: QtProperties,
93 }
94 }
95}
96
97#[derive(Debug, Copy, Clone, Type, Default, Deserialize, PartialEq)]
103#[zvariant(signature = "a{sv}")]
104pub(crate) struct Properties;
105
106impl Serialize for Properties {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: serde::ser::Serializer,
110 {
111 serializer.serialize_map(Some(0))?.end()
112 }
113}
114
115#[validate(signal: "PropertyChange")]
123#[derive(Debug, Serialize, Deserialize, PartialEq, Type)]
124pub struct EventBodyOwned {
125 #[serde(rename = "type")]
128 pub kind: String,
129
130 pub detail1: i32,
132
133 pub detail2: i32,
135
136 pub any_data: OwnedValue,
140
141 pub(crate) properties: Properties,
144}
145
146impl Default for EventBodyOwned {
147 fn default() -> Self {
148 Self {
149 kind: String::new(),
150 detail1: 0,
151 detail2: 0,
152 any_data: 0_u32.into(),
153 properties: Properties,
154 }
155 }
156}
157
158impl Clone for EventBodyOwned {
159 fn clone(&self) -> Self {
173 let cloned_any_data = self.any_data.try_clone().unwrap_or_else(|err| {
174 panic!("Failure cloning 'any_data' field: {err:?}");
175 });
176
177 Self {
178 kind: self.kind.clone(),
179 detail1: self.detail1,
180 detail2: self.detail2,
181 any_data: cloned_any_data,
182 properties: Properties,
183 }
184 }
185}
186
187#[derive(Debug, Serialize, Deserialize, PartialEq, Type)]
188pub struct EventBodyBorrowed<'a> {
189 #[serde(rename = "type")]
192 #[serde(borrow)]
193 pub kind: &'a str,
194
195 pub detail1: i32,
197
198 pub detail2: i32,
200
201 #[serde(borrow)]
204 pub any_data: Value<'a>,
205
206 #[serde(skip_deserializing)]
209 pub(crate) properties: Properties,
210}
211
212impl Default for EventBodyBorrowed<'_> {
213 fn default() -> Self {
214 Self {
215 kind: "",
216 detail1: 0,
217 detail2: 0,
218 any_data: Value::new(0_u32),
219 properties: Properties,
220 }
221 }
222}
223
224impl EventBodyBorrowed<'_> {
225 pub fn to_fully_owned(&self) -> Result<EventBodyOwned, AtspiError> {
236 let owned_any_data = self.any_data.try_to_owned()?;
237
238 Ok(EventBodyOwned {
239 kind: self.kind.into(),
240 detail1: self.detail1,
241 detail2: self.detail2,
242 any_data: owned_any_data,
243 properties: Properties,
244 })
245 }
246}
247
248impl Clone for EventBodyBorrowed<'_> {
249 fn clone(&self) -> Self {
263 let cloned_any_data = self.any_data.try_clone().unwrap_or_else(|err| {
264 panic!("Failure cloning 'any_data' field: {err:?}");
265 });
266
267 Self {
268 kind: self.kind,
269 detail1: self.detail1,
270 detail2: self.detail2,
271 any_data: cloned_any_data,
272 properties: Properties,
273 }
274 }
275}
276
277#[derive(Debug, Type, Deserialize, PartialEq)]
278pub struct EventBodyQtBorrowed<'m> {
279 #[serde(rename = "type")]
282 pub kind: &'m str,
283
284 pub detail1: i32,
286
287 pub detail2: i32,
289
290 #[serde(borrow)]
293 pub any_data: Value<'m>,
294
295 #[serde(skip_deserializing)]
298 pub(crate) properties: QtProperties,
299}
300
301impl Default for EventBodyQtBorrowed<'_> {
302 fn default() -> Self {
303 Self {
304 kind: "",
305 detail1: 0,
306 detail2: 0,
307 any_data: Value::new(0_u32),
308 properties: QtProperties,
309 }
310 }
311}
312
313impl Clone for EventBodyQtBorrowed<'_> {
314 fn clone(&self) -> Self {
328 let cloned_any_data = self.any_data.try_clone().unwrap_or_else(|err| {
329 panic!("Failure cloning 'any_data' field: {err:?}");
330 });
331
332 Self {
333 kind: self.kind,
334 detail1: self.detail1,
335 detail2: self.detail2,
336 any_data: cloned_any_data,
337 properties: QtProperties,
338 }
339 }
340}
341
342impl EventBodyQtBorrowed<'_> {
343 pub fn try_to_owned(&self) -> Result<EventBodyQtOwned, AtspiError> {
351 let any_data = self.any_data.try_to_owned()?;
352
353 Ok(EventBodyQtOwned {
354 kind: self.kind.to_owned(),
355 detail1: self.detail1,
356 detail2: self.detail2,
357 any_data,
358 properties: self.properties,
359 })
360 }
361}
362
363impl<'de> From<EventBodyQtBorrowed<'de>> for EventBodyBorrowed<'de> {
364 fn from(borrow: EventBodyQtBorrowed<'de>) -> Self {
365 let EventBodyQtBorrowed { kind, detail1, detail2, any_data, properties: _ } = borrow;
366
367 Self { kind, detail1, detail2, any_data, properties: Properties }
368 }
369}
370
371impl From<EventBodyQtOwned> for EventBodyOwned {
372 fn from(body: EventBodyQtOwned) -> Self {
373 Self {
374 kind: body.kind,
375 detail1: body.detail1,
376 detail2: body.detail2,
377 any_data: body.any_data,
378 properties: Properties,
379 }
380 }
381}
382
383#[derive(Debug, Clone, PartialEq)]
388pub enum EventBody<'a> {
389 Owned(EventBodyOwned),
390 Borrowed(EventBodyBorrowed<'a>),
391}
392
393impl Default for EventBody<'_> {
394 fn default() -> Self {
395 Self::Borrowed(EventBodyBorrowed::default())
396 }
397}
398
399impl<'a> EventBody<'_> {
400 pub fn as_owned(&self) -> Result<EventBodyOwned, AtspiError> {
409 match self {
410 Self::Owned(owned) => Ok(owned.clone()),
411 Self::Borrowed(borrowed) => borrowed.to_fully_owned(),
412 }
413 }
414
415 pub fn into_owned(self) -> Result<EventBodyOwned, AtspiError> {
424 match self {
425 Self::Owned(owned) => Ok(owned),
426 Self::Borrowed(borrowed) => borrowed.to_fully_owned(),
427 }
428 }
429
430 #[must_use]
434 pub fn kind(&'a self) -> &'a str {
435 match self {
436 Self::Owned(owned) => owned.kind.as_str(),
437 Self::Borrowed(borrowed) => borrowed.kind,
438 }
439 }
440
441 pub fn take_kind(&mut self) -> String {
446 match self {
447 Self::Owned(owned) => std::mem::take(&mut owned.kind),
448 Self::Borrowed(borrowed) => borrowed.kind.to_owned(),
449 }
450 }
451
452 #[must_use]
454 pub fn detail1(&self) -> i32 {
455 match self {
456 Self::Owned(owned) => owned.detail1,
457 Self::Borrowed(borrowed) => borrowed.detail1,
458 }
459 }
460
461 #[must_use]
463 pub fn detail2(&self) -> i32 {
464 match self {
465 Self::Owned(owned) => owned.detail2,
466 Self::Borrowed(borrowed) => borrowed.detail2,
467 }
468 }
469
470 #[must_use]
473 pub fn any_data(&'a self) -> &'a Value<'a> {
474 match self {
475 Self::Owned(owned) => &owned.any_data,
476 Self::Borrowed(borrowed) => &borrowed.any_data,
477 }
478 }
479
480 pub fn take_any_data(&mut self) -> OwnedValue {
494 match self {
495 Self::Owned(owned) => std::mem::replace(&mut owned.any_data, 0_u32.into()),
496 Self::Borrowed(borrowed) => borrowed.any_data.try_to_owned().expect("cloning 'any_data' field should not fail because we do not expect it to hold an fd"),
497 }
498 }
499}
500
501impl Type for EventBody<'_> {
502 const SIGNATURE: &'static zvariant::Signature = EventBodyOwned::SIGNATURE;
503}
504
505impl<'de> Deserialize<'de> for EventBody<'de> {
506 fn deserialize<D>(deserializer: D) -> Result<EventBody<'de>, D::Error>
507 where
508 D: serde::de::Deserializer<'de>,
509 {
510 let borrowed = EventBodyBorrowed::deserialize(deserializer)?;
511 Ok(borrowed.into())
512 }
513}
514
515impl Serialize for EventBody<'_> {
516 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
517 where
518 S: serde::ser::Serializer,
519 {
520 match self {
521 EventBody::Owned(owned) => owned.serialize(serializer),
522 EventBody::Borrowed(borrowed) => borrowed.serialize(serializer),
523 }
524 }
525}
526
527impl From<EventBodyOwned> for EventBody<'_> {
528 fn from(owned: EventBodyOwned) -> Self {
529 EventBody::Owned(owned)
530 }
531}
532
533impl<'b> From<EventBodyBorrowed<'b>> for EventBody<'b> {
534 fn from(borrowed: EventBodyBorrowed<'b>) -> Self {
535 EventBody::Borrowed(borrowed)
536 }
537}
538
539impl From<EventBodyQtOwned> for EventBody<'_> {
540 fn from(qt_owned: EventBodyQtOwned) -> Self {
541 EventBody::Owned(qt_owned.into())
542 }
543}
544
545impl<'a> From<EventBodyQtBorrowed<'a>> for EventBody<'a> {
546 fn from(qt_borrowed: EventBodyQtBorrowed<'a>) -> Self {
547 EventBody::Borrowed(qt_borrowed.into())
548 }
549}
550
551impl From<EventBodyOwned> for EventBodyQtOwned {
552 fn from(owned: EventBodyOwned) -> Self {
553 Self {
554 kind: owned.kind,
555 detail1: owned.detail1,
556 detail2: owned.detail2,
557 any_data: owned.any_data,
558 properties: QtProperties,
559 }
560 }
561}
562
563impl<'a> From<EventBodyBorrowed<'a>> for EventBodyQtOwned {
564 fn from(borrowed: EventBodyBorrowed<'a>) -> Self {
565 Self {
566 kind: borrowed.kind.to_owned(),
567 detail1: borrowed.detail1,
568 detail2: borrowed.detail2,
569 any_data: borrowed
570 .any_data
571 .try_to_owned()
572 .expect("converting borrowed to owned should not fail"),
573 properties: QtProperties,
574 }
575 }
576}
577
578impl From<EventBody<'_>> for EventBodyQtOwned {
579 fn from(event: EventBody) -> Self {
580 match event {
581 EventBody::Owned(owned) => owned.into(),
582 EventBody::Borrowed(borrowed) => borrowed.into(),
583 }
584 }
585}
586
587impl PartialEq<EventBodyOwned> for EventBodyQtOwned {
588 fn eq(&self, other: &EventBodyOwned) -> bool {
589 self.kind == other.kind
590 && self.detail1 == other.detail1
591 && self.detail2 == other.detail2
592 && self.any_data == other.any_data
593 }
594}
595
596impl PartialEq<EventBodyQtOwned> for EventBodyOwned {
597 fn eq(&self, other: &EventBodyQtOwned) -> bool {
598 self.kind == other.kind
599 && self.detail1 == other.detail1
600 && self.detail2 == other.detail2
601 && self.any_data == other.any_data
602 }
603}
604
605impl PartialEq<EventBodyBorrowed<'_>> for EventBodyQtBorrowed<'_> {
606 fn eq(&self, other: &EventBodyBorrowed<'_>) -> bool {
607 self.kind == other.kind
608 && self.detail1 == other.detail1
609 && self.detail2 == other.detail2
610 && self.any_data == other.any_data
611 }
612}
613
614impl PartialEq<EventBodyQtBorrowed<'_>> for EventBodyBorrowed<'_> {
615 fn eq(&self, other: &EventBodyQtBorrowed<'_>) -> bool {
616 self.kind == other.kind
617 && self.detail1 == other.detail1
618 && self.detail2 == other.detail2
619 && self.any_data == other.any_data
620 }
621}
622
623#[cfg(test)]
624mod test {
625 use super::*;
626 use crate::ObjectRef;
627 use std::collections::HashMap;
628 use zvariant::{serialized::Context, LE};
629 use zvariant::{Array, ObjectPath, Value};
630
631 #[test]
632 fn owned_event_body_clone() {
633 let event = EventBodyOwned::default();
634 let cloned = event.clone();
635
636 assert_eq!(event, cloned);
637 }
638
639 #[test]
640 fn event_body_qt_clone() {
641 let event = EventBodyQtOwned::default();
642 let cloned = event.clone();
643
644 assert_eq!(event, cloned);
645 }
646
647 #[test]
648 fn event_body_borrowed_clone() {
649 let event = EventBodyBorrowed::default();
650 let cloned = event.clone();
651
652 assert_eq!(event, cloned);
653 }
654
655 #[test]
656 fn event_body_qt_borrowed_clone() {
657 let event = EventBodyQtBorrowed::default();
658 let cloned = event.clone();
659
660 assert_eq!(event, cloned);
661 }
662
663 #[test]
664 fn owned_event_body_default() {
665 let event = EventBodyOwned::default();
666
667 assert_eq!(event.kind, "");
668 assert_eq!(event.detail1, 0);
669 assert_eq!(event.detail2, 0);
670 assert_eq!(event.any_data, 0_u32.into());
671 }
672
673 #[test]
674 fn qt_event_body_default() {
675 let event = EventBodyQtOwned::default();
676
677 assert_eq!(event.kind, "");
678 assert_eq!(event.detail1, 0);
679 assert_eq!(event.detail2, 0);
680 assert_eq!(event.any_data, 0_u32.into());
681 assert_eq!(event.properties, QtProperties);
682 }
683
684 #[test]
685 fn event_body_borrowed_default() {
686 let event = EventBodyBorrowed::default();
687
688 assert_eq!(event.kind, "");
689 assert_eq!(event.detail1, 0);
690 assert_eq!(event.detail2, 0);
691 assert_eq!(event.any_data, Value::new(0_u32));
692 }
693
694 #[test]
695 fn qt_event_body_borrowed_default() {
696 let event = EventBodyQtBorrowed::default();
697
698 assert_eq!(event.kind, "");
699 assert_eq!(event.detail1, 0);
700 assert_eq!(event.detail2, 0);
701 assert_eq!(event.any_data, Value::new(0_u32));
702 assert_eq!(event.properties, QtProperties);
703 }
704
705 #[test]
706 fn event_body_default() {
707 let event = EventBody::default();
708
709 assert_eq!(event, EventBody::Borrowed(EventBodyBorrowed::default()));
710 }
711
712 #[test]
713 fn qt_to_owned() {
714 let qt = EventBodyQtOwned::default();
715 let owned: EventBodyOwned = EventBodyQtOwned::default().into();
716
717 assert_eq!(owned, qt);
718 }
719
720 #[test]
721 fn borrowed_to_qt() {
722 let borrowed: EventBodyBorrowed = EventBodyQtBorrowed::default().into();
723
724 assert_eq!(borrowed, EventBodyBorrowed::default());
725 }
726
727 #[test]
728 fn event_body_deserialize_as_owned() {
729 let event = EventBodyOwned::default();
730
731 let ctxt = Context::new_dbus(LE, 0);
732 let bytes = zvariant::to_bytes::<EventBodyOwned>(ctxt, &event).unwrap();
733
734 let (deserialized, _) = bytes.deserialize::<EventBodyOwned>().unwrap();
735
736 assert_eq!(deserialized, event);
737 }
738
739 #[test]
740 fn owned_event_body_deserialize_as_borrowed() {
741 let event = EventBodyOwned::default();
742
743 let ctxt = Context::new_dbus(LE, 0);
744 let bytes = zvariant::to_bytes::<EventBodyOwned>(ctxt, &event).unwrap();
745
746 let (deserialized, _) = bytes.deserialize::<EventBodyBorrowed>().unwrap();
747
748 assert_eq!(deserialized, EventBodyBorrowed::default());
749 assert_eq!(deserialized.kind, event.kind.as_str());
750 assert_eq!(deserialized.detail1, event.detail1);
751 assert_eq!(deserialized.detail2, event.detail2);
752 assert_eq!(deserialized.any_data, *event.any_data);
753 }
754
755 #[test]
756 fn qt_owned_event_body_deserialize_as_borrowed() {
757 let event = EventBodyQtOwned::default();
758
759 let ctxt = Context::new_dbus(LE, 0);
760 let bytes = zvariant::to_bytes::<EventBodyQtOwned>(ctxt, &event).unwrap();
761
762 let (deserialized, _) = bytes.deserialize::<EventBodyBorrowed>().unwrap();
763
764 assert_eq!(deserialized, EventBodyBorrowed::default());
765 assert_eq!(deserialized.kind, event.kind.as_str());
766 assert_eq!(deserialized.detail1, event.detail1);
767 assert_eq!(deserialized.detail2, event.detail2);
768 assert_eq!(deserialized.any_data, *event.any_data);
769 }
770
771 #[test]
772 fn event_body_default_deserialize_as_event_body() {
773 let event = EventBody::default();
774
775 let ctxt = Context::new_dbus(LE, 0);
776 let bytes = zvariant::to_bytes::<EventBody>(ctxt, &event).unwrap();
777
778 let (deserialized, _) = bytes.deserialize::<EventBody>().unwrap();
779
780 assert_eq!(deserialized, event);
781 }
782
783 #[test]
784 fn event_body_owned_default_deserialize_as_event_body() {
785 let event = EventBodyOwned::default();
786
787 let ctxt = Context::new_dbus(LE, 0);
788 let bytes = zvariant::to_bytes::<EventBodyOwned>(ctxt, &event).unwrap();
789
790 let (deserialized, _) = bytes.deserialize::<EventBody>().unwrap();
791
792 assert_eq!(deserialized.kind(), event.kind.as_str());
793 assert_eq!(deserialized.detail1(), event.detail1);
794 assert_eq!(deserialized.detail2(), event.detail2);
795 assert_eq!(*deserialized.any_data(), *event.any_data);
796 }
797
798 #[test]
799 fn complex_body_deserialize_as_event_body() {
800 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
801 let boots = Value::from(boots);
802 let event = (
803 "object:state-changed:focused",
804 1,
805 2,
806 boots.clone(),
807 HashMap::from([("key", Value::from(55_u32)), ("key2", Value::from(56_u32))]),
808 );
809
810 let ctxt = Context::new_dbus(LE, 0);
811 let bytes =
812 zvariant::to_bytes::<(&str, i32, i32, Value, HashMap<&str, Value>)>(ctxt, &event)
813 .unwrap();
814
815 let (deserialized, _) = bytes.deserialize::<EventBody>().unwrap();
816
817 assert_eq!(deserialized.kind(), "object:state-changed:focused");
818 assert_eq!(deserialized.detail1(), 1);
819 assert_eq!(deserialized.detail2(), 2);
820 assert_eq!(*deserialized.any_data(), boots);
821 }
822
823 #[test]
824 fn complex_body_deserialize_as_owned_event_body() {
825 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
826 let boots = Value::from(boots);
827 let event = (
828 "object:state-changed:focused",
829 1,
830 2,
831 boots.clone(),
832 HashMap::from([("key", Value::from(55_u32)), ("key2", Value::from(56_u32))]),
833 );
834
835 let ctxt = Context::new_dbus(LE, 0);
836 let bytes =
837 zvariant::to_bytes::<(&str, i32, i32, Value, HashMap<&str, Value>)>(ctxt, &event)
838 .unwrap();
839
840 let (deserialized, _) = bytes.deserialize::<EventBodyOwned>().unwrap();
841
842 assert_eq!(deserialized.kind, "object:state-changed:focused");
843 assert_eq!(deserialized.detail1, 1);
844 assert_eq!(deserialized.detail2, 2);
845 assert_eq!(*deserialized.any_data, boots);
846 }
847
848 #[test]
849 fn complex_qt_body_as_bytes_deserialize_as_event_body() {
850 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
851 let boots = Value::from(boots);
852 let event = (
853 "and that is what they'll do",
854 1,
855 2,
856 boots.clone(),
857 (":0.0", ObjectPath::from_static_str_unchecked("/")),
858 );
859
860 let ctxt = Context::new_dbus(LE, 0);
861 let bytes = zvariant::to_bytes::<(&str, i32, i32, Value, (&str, ObjectPath))>(ctxt, &event)
862 .unwrap();
863
864 let (deserialized, _) = bytes.deserialize::<EventBody>().unwrap();
865
866 assert_eq!(deserialized.kind(), "and that is what they'll do");
867 assert_eq!(deserialized.detail1(), 1);
868 assert_eq!(deserialized.detail2(), 2);
869 assert_eq!(*deserialized.any_data(), boots);
870 }
871
872 #[test]
873 fn complex_qt_body_as_message_deserialize_as_event_body() {
874 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
875 let boots = Value::from(boots);
876 let event = (
877 "and that is what they'll do",
878 1,
879 2,
880 boots.clone(),
881 (":0.0", ObjectPath::from_static_str_unchecked("/")),
882 );
883
884 let msg = zbus::Message::signal("/", "org.a11y.atspi.Object", "StateChange")
885 .unwrap()
886 .build(&event)
887 .unwrap();
888
889 let body = msg.body();
890 let deserialized = body.deserialize_unchecked::<EventBody>().unwrap();
891
892 assert_eq!(deserialized.kind(), "and that is what they'll do");
893 assert_eq!(deserialized.detail1(), 1);
894 assert_eq!(deserialized.detail2(), 2);
895 assert_eq!(*deserialized.any_data(), boots);
896 }
897
898 #[test]
899 fn illegal_body_as_bytes_deserialize_as_event_body() {
900 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
901 let boots = Value::from(boots);
902 let event = (
903 "and that is what they'll do",
904 1,
905 2,
906 4_u32,
907 boots.clone(),
908 (":0.0", ObjectPath::from_static_str_unchecked("/")),
909 );
910
911 let ctxt = Context::new_dbus(LE, 0);
912 let bytes = zvariant::to_bytes::<(&str, i32, i32, u32, Value<'_>, (&str, ObjectPath<'_>))>(
913 ctxt, &event,
914 )
915 .unwrap();
916
917 assert!(bytes.deserialize::<EventBody>().is_err());
918 }
919
920 #[test]
921 fn complex_body_deserialize_as_borrowed_event_body() {
922 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
923 let boots = Value::from(boots);
924 let event = (
925 "object:state-changed:focused",
926 1,
927 2,
928 boots.clone(),
929 HashMap::from([("key", Value::from(55_u32)), ("key2", Value::from(56_u32))]),
930 );
931
932 let ctxt = Context::new_dbus(LE, 0);
933 let bytes =
934 zvariant::to_bytes::<(&str, i32, i32, Value, HashMap<&str, Value>)>(ctxt, &event)
935 .unwrap();
936
937 let (deserialized, _) = bytes.deserialize::<EventBodyBorrowed>().unwrap();
938
939 assert_eq!(deserialized.kind, "object:state-changed:focused");
940 assert_eq!(deserialized.detail1, 1);
941 assert_eq!(deserialized.detail2, 2);
942 assert_eq!(deserialized.any_data, boots);
943 }
944
945 #[test]
946 fn deserialize_message_from_complex_message_data() {
947 let boots = Array::from(vec!["these", "boots", "are", "made", "for", "walking"]);
948 let boots = Value::from(boots);
949 let body = (
950 "object:state-changed:focused",
951 1,
952 2,
953 boots.clone(),
954 HashMap::from([("key", Value::from(55_u32)), ("key2", Value::from(56_u32))]),
955 );
956
957 let message = zbus::Message::signal("/", "org.a11y.atspi.Object", "StateChange")
958 .unwrap()
959 .build(&body)
960 .unwrap();
961
962 let msg_body = message.body();
963
964 let deserialized = msg_body.deserialize::<EventBodyOwned>().unwrap();
965
966 assert_eq!(deserialized.kind, "object:state-changed:focused");
967 assert_eq!(deserialized.detail1, 1);
968 assert_eq!(deserialized.detail2, 2);
969 assert_eq!(*deserialized.any_data, boots);
970 }
971
972 #[test]
973 fn simple_data_deserialization() {
974 let body = "hello";
975
976 let message = zbus::Message::signal("/bus/driver/zeenix", "org.Zbus", "TicketCheck")
977 .unwrap()
978 .build(&body)
979 .unwrap();
980
981 let msg_body = message.body();
982 let deserialized = msg_body.deserialize::<&str>().unwrap();
983
984 assert_eq!(deserialized, body);
985 }
986
987 #[test]
988 fn test_valid_hashmap_of_string_value_deserializes_as_properties() {
989 let val = Value::from(0_u32);
990 let key = "test";
991 let map = HashMap::from([(key, val)]);
992
993 let ctxt = Context::new_dbus(LE, 0);
994 let bytes = zvariant::to_bytes::<HashMap<&str, Value>>(ctxt, &map).unwrap();
995
996 let (properties, _) = bytes.deserialize::<Properties>().unwrap();
997
998 assert_eq!(properties, Properties);
999 }
1000
1001 #[test]
1002 fn test_object_ref_deserializes_as_qt_properties() {
1003 let object_ref = ObjectRef::default();
1004
1005 let ctxt = Context::new_dbus(LE, 0);
1006 let bytes = zvariant::to_bytes::<ObjectRef>(ctxt, &object_ref).unwrap();
1007
1008 let (qt_props, _) = bytes.deserialize::<QtProperties>().unwrap();
1009
1010 assert_eq!(qt_props, QtProperties);
1011 }
1012
1013 #[test]
1014 fn test_properties_serializes_as_valid_hashmap() {
1015 let properties = Properties;
1016 let ctxt = Context::new_dbus(LE, 0);
1017 let bytes = zvariant::to_bytes::<Properties>(ctxt, &properties).unwrap();
1018
1019 let (map, _) = bytes.deserialize::<HashMap<&str, Value>>().unwrap();
1020
1021 assert_eq!(map, HashMap::new());
1022 }
1023
1024 #[test]
1025 fn test_qt_properties_serializes_as_valid_string_objpath_tuple() {
1026 let qt_properties = QtProperties;
1027 let ctxt = Context::new_dbus(LE, 0);
1028 let bytes = zvariant::to_bytes::<QtProperties>(ctxt, &qt_properties).unwrap();
1029
1030 let (tuple, _) = bytes.deserialize::<(&str, ObjectPath)>().unwrap();
1031
1032 assert_eq!(tuple, (":0.0", ObjectPath::from_static_str_unchecked("/")));
1033 }
1034
1035 #[test]
1036 fn test_qt_properties_serializes_as_valid_object_ref() {
1037 let qt_properties = QtProperties;
1038 let ctxt = Context::new_dbus(LE, 0);
1039 let bytes = zvariant::to_bytes::<QtProperties>(ctxt, &qt_properties).unwrap();
1040
1041 let (objectref, _) = bytes.deserialize::<ObjectRef>().unwrap();
1042
1043 assert_eq!(objectref.name().unwrap().as_str(), ":0.0");
1044 assert_eq!(objectref.path(), &ObjectPath::from_static_str_unchecked("/"));
1045 }
1046
1047 #[cfg(test)]
1048 mod signatures {
1049 use crate::events::EventBodyQtOwned;
1050 use zvariant::{signature::Fields, Signature, Type};
1051
1052 #[test]
1053 fn test_event_body_signature_equals_borrowed_event_body_signature() {
1054 use super::*;
1055 use zvariant::Type;
1056
1057 let borrowed = EventBodyBorrowed::SIGNATURE;
1058 let owned = EventBodyOwned::SIGNATURE;
1059
1060 assert_eq!(borrowed, owned);
1061 }
1062
1063 const QSPI_EVENT_SIGNATURE: &Signature = &Signature::static_structure(&[
1067 &Signature::Str,
1068 &Signature::I32,
1069 &Signature::I32,
1070 &Signature::Variant,
1071 &Signature::Structure(Fields::Static {
1072 fields: &[&Signature::Str, &Signature::ObjectPath],
1073 }),
1074 ]);
1075
1076 #[test]
1077 fn check_event_body_qt_signature() {
1078 assert_eq!(<EventBodyQtOwned as Type>::SIGNATURE, QSPI_EVENT_SIGNATURE);
1079 }
1080 }
1081}