1macro_rules! impl_event_properties {
24 ($type:ty) => {
25 impl crate::EventProperties for $type {
26 fn sender(&self) -> zbus_names::UniqueName<'_> {
27 self.item
28 .name()
29 .expect("Events are received with valid ObjetRef")
30 .as_ref()
31 }
32
33 fn path(&self) -> zvariant::ObjectPath<'_> {
34 self.item.path().as_ref()
35 }
36 }
37 };
38}
39
40macro_rules! impl_from_object_ref {
57 ($type:ty) => {
58 impl From<crate::ObjectRef<'_>> for $type {
59 fn from(obj_ref: crate::ObjectRef) -> Self {
60 Self { item: obj_ref.into() }
61 }
62 }
63 };
64}
65
66#[cfg(feature = "wrappers")]
67macro_rules! impl_from_interface_event_enum_for_event {
83 ($outer_type:ty, $outer_variant:path) => {
84 #[cfg(feature = "wrappers")]
85 impl From<$outer_type> for Event {
86 fn from(event_variant: $outer_type) -> Event {
87 $outer_variant(event_variant.into())
88 }
89 }
90 };
91}
92
93#[cfg(feature = "wrappers")]
94macro_rules! impl_try_from_event_for_interface_enum {
115 ($outer_type:ty, $outer_variant:path) => {
116 impl TryFrom<Event> for $outer_type {
117 type Error = AtspiError;
118 fn try_from(generic_event: Event) -> Result<$outer_type, Self::Error> {
119 if let $outer_variant(event_type) = generic_event {
120 Ok(event_type)
121 } else {
122 Err(AtspiError::Conversion("Invalid type"))
123 }
124 }
125 }
126 };
127}
128
129#[cfg(feature = "wrappers")]
130macro_rules! impl_from_user_facing_event_for_interface_event_enum {
147 ($inner_type:ty, $outer_type:ty, $inner_variant:path) => {
148 impl From<$inner_type> for $outer_type {
149 fn from(specific_event: $inner_type) -> $outer_type {
150 $inner_variant(specific_event)
151 }
152 }
153 };
154}
155
156#[cfg(feature = "wrappers")]
157macro_rules! impl_from_user_facing_type_for_event_enum {
177 ($inner_type:ty, $outer_variant:path) => {
178 #[cfg(feature = "wrappers")]
179 impl From<$inner_type> for Event {
180 fn from(event_variant: $inner_type) -> Event {
181 $outer_variant(event_variant.into())
182 }
183 }
184 };
185}
186
187#[cfg(feature = "wrappers")]
188macro_rules! impl_try_from_event_for_user_facing_type {
218 ($inner_type:ty, $inner_variant:path, $outer_variant:path) => {
219 #[cfg(feature = "wrappers")]
220 impl TryFrom<crate::Event> for $inner_type {
221 type Error = AtspiError;
222 fn try_from(generic_event: crate::Event) -> Result<$inner_type, Self::Error> {
223 if let $outer_variant($inner_variant(specific_event)) = generic_event {
224 Ok(specific_event)
225 } else {
226 Err(AtspiError::Conversion("Invalid type"))
227 }
228 }
229 }
230 };
231}
232
233macro_rules! impl_to_dbus_message {
257 ($type:ty) => {
258 #[cfg(feature = "zbus")]
259 impl TryFrom<$type> for zbus::Message {
260 type Error = AtspiError;
261 fn try_from(event: $type) -> Result<Self, Self::Error> {
262 use crate::events::{DBusInterface, DBusMember, MessageConversion};
263 Ok(zbus::Message::signal(
264 event.path(),
265 <$type as DBusInterface>::DBUS_INTERFACE,
266 <$type as DBusMember>::DBUS_MEMBER,
267 )?
268 .sender(event.sender().to_string())?
269 .build(&event.body())?)
270 }
271 }
272 };
273}
274
275macro_rules! impl_from_dbus_message {
299 ($type:ty) => {
300 impl_from_dbus_message!($type, Auto);
301 };
302
303 ($type:ty, Auto) => {
304 #[cfg(feature = "zbus")]
305 impl<'msg> TryFrom<&'msg zbus::Message> for $type {
306 type Error = AtspiError;
307 fn try_from(msg: &'msg zbus::Message) -> Result<Self, Self::Error> {
308 use crate::events::{EventBody, EventBodyQtBorrowed};
309 use crate::events::traits::{MessageConversion, MessageConversionExt};
310 use zvariant::Type;
311 use crate::ObjectRef;
312
313 let hdr = msg.header();
314 <Self as MessageConversionExt<<Self as MessageConversion>::Body<'_>>>::validate_interface(&hdr)?;
315 <Self as MessageConversionExt<<Self as MessageConversion>::Body<'_>>>::validate_member(&hdr)?;
316 let item = ObjectRef::try_from(&hdr)?;
317
318 let body = msg.body();
319 let signature = body.signature();
320
321 if signature == EventBody::SIGNATURE || signature == EventBodyQtBorrowed::SIGNATURE {
322 Ok(Self::from_message_unchecked_parts(item, body)?)
323 } else {
324 Err(AtspiError::SignatureMatch(format!(
325 "signature mismatch: expected: {}, signal body: {}",
326 msg.body().signature(),
327 <Self as MessageConversion>::Body::SIGNATURE,
328 )))
329 }
330 }
331 }
332 };
333
334 ($type:ty, Explicit) => {
335 #[cfg(feature = "zbus")]
336 impl TryFrom<&zbus::Message> for $type {
337 type Error = crate::AtspiError;
338 fn try_from(msg: &zbus::Message) -> Result<Self, Self::Error> {
339 let hdr = msg.header();
340 <$type as crate::events::MessageConversionExt<<$type as MessageConversion>::Body<'_>>>::try_from_message(msg, &hdr)
341 }
342 }
343 };
344}
345
346#[cfg(test)]
358macro_rules! generic_event_test_case {
359 ($type:ty) => {
360 #[test]
361 fn generic_event_uses() {
362 use crate::events::traits::MessageConversion;
363
364 let event_struct = <$type>::default();
365 assert_eq!(event_struct.path().as_str(), crate::object_ref::TEST_OBJECT_PATH_STR);
366 assert_eq!(event_struct.sender().as_str(), crate::object_ref::TEST_OBJECT_BUS_NAME);
367 let body = event_struct.body();
368 let body2 = Message::method_call(
369 event_struct.path().as_str(),
370 <$type as crate::events::DBusMember>::DBUS_MEMBER,
371 )
372 .unwrap()
373 .sender(event_struct.sender().as_str())
374 .unwrap()
375 .build(&(body,))
376 .unwrap();
377 let header = body2.header();
378 let build_struct = <$type>::from_message_unchecked(&body2, &header)
379 .expect("<$type as Default>'s parts should build a valid ObjectRef");
380 assert_eq!(event_struct, build_struct);
381 }
382 };
383}
384
385#[cfg(test)]
396macro_rules! event_has_matching_xml_definition {
397 ($type:ty) => {
398 #[test]
399 fn event_has_matching_xml_definition() {
400
401 use zbus_xml;
402 use crate::events::{DBusInterface, DBusMember};
403
404 let fname = match <$type>::DBUS_INTERFACE.split(".").last().expect("Has last section") {
405 "Cache" => "xml/Cache.xml",
406 "Socket" => "xml/Socket.xml",
407 "Registry" => "xml/Registry.xml",
408 _ => "xml/Event.xml",
409 };
410
411 let reader = std::fs::File::open(fname).expect("Valid file path!");
412 let xml = zbus_xml::Node::from_reader(reader).expect("Valid DBus XML file!");
413 let Some(interface) = xml.interfaces().iter().find(|int| int.name() == <$type>::DBUS_INTERFACE) else {
414
415 let possible_names: Vec<String> = xml.interfaces().iter().map(|int| int.name().as_str().to_string()).collect();
416 panic!("{} has interface name {}, but it was not found in the list of interfaces defined in the XML: {:?}", std::any::type_name::<$type>(), <$type>::DBUS_INTERFACE, possible_names);
417 };
418 let Some(_member) = interface.signals().iter().find(|mem| mem.name() == <$type>::DBUS_MEMBER) else {
419 let possible_names: Vec<String> = interface.signals().iter().map(|mem| mem.name().as_str().to_string()).collect();
420 panic!("{} has interface name {} and member name {}, but it was not found in the list of members defined in the corresponding interface in the XML: {:?}", std::any::type_name::<$type>(), <$type>::DBUS_INTERFACE, <$type>::DBUS_MEMBER, possible_names);
421 };
422 }
423 };
424}
425
426#[cfg(test)]
427macro_rules! zbus_message_qtspi_test_case {
428 ($type:ty, Auto) => {
429 #[cfg(feature = "zbus")]
430 #[test]
431 fn zbus_message_conversion_qtspi() {
432 use crate::events::EventTypeProperties;
433 use crate::events::MessageConversion;
434
435 let ev = <$type>::default();
438 let qt: crate::events::EventBodyQtOwned = ev.body().into();
439 let msg = zbus::Message::signal(
440 ev.path(),
441 ev.interface(),
442 ev.member(),
443 )
444 .unwrap()
445 .sender(":0.0")
446 .unwrap()
447 .build(&(qt,))
448 .unwrap();
449 <$type>::try_from(&msg).expect("Should be able to use an EventBodyQtOwned for any type whose BusProperties::Body = EventBodyOwned");
450 }
451 #[cfg(feature = "zbus")]
452 #[test]
453 fn zbus_message_conversion_qtspi_event_enum() {
454 use crate::events::EventTypeProperties;
455 use crate::events::MessageConversion;
456 use crate::Event;
457
458 let ev = <$type>::default();
461 let qt: crate::events::EventBodyQtOwned = ev.body().into();
462 let msg = zbus::Message::signal(
463 ev.path(),
464 ev.interface(),
465 ev.member(),
466 )
467 .unwrap()
468 .sender(":0.0")
469 .unwrap()
470 .build(&(qt,))
471 .unwrap();
472 assert_matches!(Event::try_from(&msg), Ok(_));
473 }
474 };
475 ($type:ty, Explicit) => {};
476}
477
478#[cfg(test)]
484macro_rules! zbus_message_test_case {
485 ($type:ty) => {
486 zbus_message_test_case!($type, Auto);
487 };
488 ($type:ty, $extra:tt) => {
489 zbus_message_qtspi_test_case!($type, $extra);
490 #[cfg(feature = "zbus")]
491 #[test]
492 fn zbus_msg_conversion_to_specific_event_type() {
493 let struct_event = <$type>::default();
494 let msg: zbus::Message = zbus::Message::try_from(<$type>::default()).expect("Should convert a `$type::default()` into a message. Check the `impl_to_dbus_message` macro .");
495
496 let struct_event_back =
497 <$type>::try_from(&msg).expect("Should convert from `$type::default()` originated `Message` back into a specific event type. Check the `impl_from_dbus_message` macro.");
498 assert_eq!(struct_event, struct_event_back, "Events converted into a message and back must be the same");
499 }
500
501 #[cfg(feature = "zbus")]
502 #[test]
503 fn zbus_msg_conversion_to_event_enum_type() {
504 let struct_event = <$type>::default();
505 let msg: zbus::Message = zbus::Message::try_from(struct_event.clone()).expect("Should convert a `$type::default()` into a message. Check the `impl_to_dbus_message` macro.");
506 let event_enum_back =
507 crate::Event::try_from(&msg).expect("Should convert a from `$type::default()` built `Message` into an event enum. Check the `impl_from_dbus_message` macro.");
508 let event_enum: crate::Event = struct_event.into();
509 assert_eq!(event_enum, event_enum_back);
510 }
511 #[cfg(feature = "zbus")]
514 #[test]
515 fn zbus_msg_conversion_failure_fake_msg() -> () {
516 let fake_msg = zbus::Message::signal(
517 "/org/a11y/sixtynine/fourtwenty",
518 "org.a11y.atspi.technically.valid",
519 "MadeUpMember",
520 )
521 .unwrap()
522 .sender(":0.0")
523 .unwrap()
524 .build(&())
525 .unwrap();
526 let event = <$type>::try_from(&fake_msg);
527 assert_matches!(event, Err(_), "This conversion should fail");
528 }
529
530 #[cfg(feature = "zbus")]
531 #[test]
532 fn zbus_msg_conversion_validated_message_with_body() -> () {
533 use crate::events::MessageConversion;
534
535 let fake_msg = zbus::Message::signal(
536 "/org/a11y/sixtynine/fourtwenty",
537 "org.a11y.atspi.technically.valid",
538 "MadeUpMember",
539 )
540 .unwrap()
541 .sender(":0.0")
542 .unwrap()
543 .build(&<$type>::default().body())
544 .unwrap();
545 let hdr = fake_msg.header();
546 let event = <$type>::from_message_unchecked(&fake_msg, &hdr);
547 event.expect("The from_message_unchecked function should work, despite mismatching interface and member");
548 }
549
550 #[cfg(feature = "zbus")]
551 #[test]
552 fn zbus_msg_conversion_failure_correct_interface() -> () {
553 let fake_msg = zbus::Message::signal(
554 "/org/a11y/sixtynine/fourtwenty",
555 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
556 "MadeUpMember",
557 )
558 .unwrap()
559 .sender(":0.0")
560 .unwrap()
561 .build(&())
562 .unwrap();
563 let event = <$type>::try_from(&fake_msg);
564 assert_matches!(event, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
565 }
566
567 #[cfg(feature = "zbus")]
568 #[test]
569 fn zbus_msg_conversion_failure_correct_interface_and_member() -> () {
570 let fake_msg = zbus::Message::signal(
571 "/org/a11y/sixtynine/fourtwenty",
572 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
573 <$type as crate::events::DBusMember>::DBUS_MEMBER,
574 )
575 .unwrap()
576 .sender(":0.0")
577 .unwrap()
578 .build(&())
579 .unwrap();
580 let event = <$type>::try_from(&fake_msg);
581 assert_matches!(event, Err(AtspiError::SignatureMatch(_)), "Wrong kind of error");
582 }
583
584 #[cfg(feature = "zbus")]
585 #[test]
586 fn zbus_msg_conversion_failure_correct_interface_and_member_invalid_body() -> () {
587 let invalid_body: (i32, u64, String, String) = (0, 0, String::new(), String::new());
589 let fake_msg = zbus::Message::signal(
590 "/org/a11y/sixtynine/fourtwenty",
591 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
592 <$type as crate::events::DBusMember>::DBUS_MEMBER,
593 )
594 .unwrap()
595 .sender(":0.0")
596 .unwrap()
597 .build(&invalid_body)
598 .unwrap();
599 let event = <$type>::try_from(&fake_msg);
600 assert_matches!(event, Err(AtspiError::SignatureMatch(_)), "Wrong kind of error");
601 }
602
603 #[cfg(feature = "zbus")]
604 #[test]
605 fn zbus_msg_conversion_failure_correct_body() -> () {
606 use crate::events::MessageConversion;
607 let fake_msg = zbus::Message::signal(
608 "/org/a11y/sixtynine/fourtwenty",
609 "org.a11y.atspi.accessible.technically.valid",
610 "FakeMember",
611 )
612 .unwrap()
613 .sender(":0.0")
614 .unwrap()
615 .build(&<$type>::default().body())
616 .unwrap();
617 let event = <$type>::try_from(&fake_msg);
618 assert_matches!(event, Err(_));
619 }
620
621 #[cfg(feature = "zbus")]
622 #[test]
623 fn zbus_msg_conversion_failure_correct_body_and_member() -> () {
624 use crate::events::MessageConversion;
625
626 let fake_msg = zbus::Message::signal(
627 "/org/a11y/sixtynine/fourtwenty",
628 "org.a11y.atspi.accessible.technically.valid",
629 <$type as crate::events::DBusMember>::DBUS_MEMBER,
630 )
631 .unwrap()
632 .sender(":0.0")
633 .unwrap()
634 .build(&<$type>::default().body())
635 .unwrap();
636 let event = <$type>::try_from(&fake_msg);
637 assert_matches!(event, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
638 }
639 #[cfg(feature = "zbus")]
640 #[test]
641 fn zbus_msg_conversion_failure_correct_body_and_interface() -> () {
642 use crate::events::MessageConversion;
643
644 let fake_msg = zbus::Message::signal(
645 "/org/a11y/sixtynine/fourtwenty",
646 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
647 "MadeUpMember",
648 )
649 .unwrap()
650 .sender(":0.0")
651 .unwrap()
652 .build(&<$type>::default().body())
653 .unwrap();
654 let event = <$type>::try_from(&fake_msg);
655 assert_matches!(event, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
656 }
657 };
658}
659
660#[cfg(feature = "wrappers")]
661macro_rules! event_wrapper_test_cases {
682 ($iface_enum:ty, $ufet:ty) => {
684 #[cfg(test)]
685 #[rename_item::rename(name($iface_enum), prefix = "events_tests_", case = "snake")]
686 mod foo {
687 use super::{$ufet, $iface_enum, AtspiError, Event, MessageConversion};
688
689 use assert_matches::assert_matches;
691
692 #[test]
693 fn into_and_try_from_user_facing_event() {
694 let sub_type = <$ufet>::default();
696
697 let mod_type = <$iface_enum>::from(sub_type);
699 let hint_iface = "Check macro `impl_from_user_facing_event_for_interface_event_enum!`";
700
701 let event = Event::from(mod_type.clone());
703 let hint_event = "Check macro `impl_from_interface_event_enum_for_event!`";
704
705 let hint_event_try = "Check macro `impl_try_from_event_for_interface_enum!`";
707 let mod_type2 = <$iface_enum>::try_from(event.clone())
708 .expect("Should convert outer `Event` enum into interface enum. hints: {hint_event} and {hint_event_try}");
709
710 assert_eq!(
711 mod_type, mod_type2,
712 "Interface enums should match. hint: {hint_iface}, {hint_event} and {hint_event_try}"
713 );
714 }
715
716 #[cfg(feature = "zbus")]
717 #[test]
718 fn zbus_msg_invalid_interface() {
719 let fake_msg = zbus::Message::signal(
720 "/org/a11y/sixtynine/fourtwenty",
721 "org.a11y.atspi.technically.valid.lol",
722 <$ufet as crate::events::DBusMember>::DBUS_MEMBER,
723 )
724 .unwrap()
725 .sender(":0.0")
726 .unwrap()
727 .build(&<$ufet>::default().body())
728 .unwrap();
729
730 let mod_type = <$iface_enum>::try_from(&fake_msg);
743 let event_type = Event::try_from(&fake_msg);
744
745 assert_matches!(mod_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
746 assert_matches!(event_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
747 }
748
749 #[cfg(feature = "zbus")]
750 #[test]
751 fn zbus_msg_invalid_member() {
752 let fake_msg = zbus::Message::signal(
753 "/org/a11y/sixtynine/fourtwenty",
754 <$ufet as crate::events::DBusInterface>::DBUS_INTERFACE,
755 "FakeFunctionLol",
756 )
757 .unwrap()
758 .sender(":0.0")
759 .unwrap()
760 .build(&<$ufet>::default().body())
761 .unwrap();
762 let mod_type = <$iface_enum>::try_from(&fake_msg);
764 assert_matches!(mod_type, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
765 }
766 #[cfg(feature = "zbus")]
767 #[test]
768 fn zbus_msg_invalid_member_and_interface() {
769 let fake_msg = zbus::Message::signal(
770 "/org/a11y/sixtynine/fourtwenty",
771 "org.a11y.atspi.technically.allowed",
772 "FakeFunctionLol",
773 )
774 .unwrap()
775 .sender(":0.0")
776 .unwrap()
777 .build(&<$ufet>::default().body())
778 .unwrap();
779 let mod_type = <$iface_enum>::try_from(&fake_msg);
781
782 assert_matches!(mod_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
784 }
785
786 #[cfg(feature = "zbus")]
787 #[test]
788 fn zbus_msg_conversion() {
789 let valid_msg = zbus::Message::signal(
790 "/org/a11y/sixtynine/fourtwenty",
791 <$ufet as crate::events::DBusInterface>::DBUS_INTERFACE,
792 <$ufet as crate::events::DBusMember>::DBUS_MEMBER,
793 )
794 .unwrap()
795 .sender(":0.0")
796 .unwrap()
797 .build(&<$ufet>::default().body())
798 .unwrap();
799 let mod_type = <$iface_enum>::try_from(&valid_msg);
801 mod_type.expect("Should convert from `$ufet::default()` built `Message` back into a interface event enum variant wrapping an inner type. Check the `impl_from_dbus_message` macro.");
802 }
803
804
805 }
806 };
807}
808
809macro_rules! event_test_cases {
810 ($ufet:ty) => {
811 event_test_cases!($ufet, Auto);
812 };
813 ($ufet:ty, $qt:tt) => {
814 #[cfg(test)]
815 #[rename_item::rename(name($ufet), prefix = "event_tests_", case = "snake")]
816 mod foo {
817 use super::{$ufet, AtspiError, EventProperties };
818 use crate::events::traits::EventTypeProperties;
819 #[cfg(feature = "zbus")]
820 use zbus::Message;
821 use crate::Event;
822
823 use assert_matches::assert_matches;
825
826 #[test]
827 #[cfg(feature = "wrappers")]
828 fn event_enum_conversion() {
829 let event_struct = <$ufet>::default();
830 let event_enum = Event::from(event_struct.clone());
831 let event_struct_back = <$ufet>::try_from(event_enum)
832 .expect("Should convert event enum into specific event type because it was created from it. Check the `impl_from_interface_event_enum_for_event` macro");
833 assert_eq!(event_struct, event_struct_back);
834 }
835
836 #[test]
837 #[cfg(feature = "wrappers")]
838 fn event_enum_transparency_test_case() {
839 let specific_event = <$ufet>::default();
840
841 let generic_event = Event::from(specific_event.clone());
842 let hint = "Check macro `impl_from_user_facing_type_for_event_enum!`.";
843
844 assert_eq!(
845 specific_event.member(),
846 generic_event.member(),
847 "DBus members do not match. hint: {hint}"
848 );
849 assert_eq!(
850 specific_event.interface(),
851 generic_event.interface(),
852 "DBus interfaces do not match. hint: {hint}"
853 );
854 assert_eq!(
855 specific_event.registry_string(),
856 generic_event.registry_string(),
857 "Registry strings do not match. hint: {hint}"
858 );
859 assert_eq!(
860 specific_event.match_rule(),
861 generic_event.match_rule(),
862 "Match rule strings do not match. hint: {hint}"
863 );
864 assert_eq!(specific_event.path(), generic_event.path(), "Paths do not match. hint: {hint}");
865 assert_eq!(specific_event.sender(), generic_event.sender(), "Senders do not match. hint: {hint}");
866 }
867
868 zbus_message_test_case!($ufet, $qt);
869 event_has_matching_xml_definition!($ufet);
870 generic_event_test_case!($ufet);
871 }
872 assert_impl_all!(
873 $ufet: Clone,
874 std::fmt::Debug,
875 serde::Serialize,
876 serde::Deserialize<'static>,
877 Default,
878 PartialEq,
879 Eq,
880 std::hash::Hash,
881 crate::events::traits::EventProperties,
882 crate::events::traits::EventTypeProperties,
883 crate::events::traits::DBusInterface,
884 crate::events::traits::DBusMember,
885 crate::events::traits::DBusMatchRule,
886 crate::events::traits::RegistryEventString
887 );
888
889 #[cfg(feature = "zbus")]
890 assert_impl_all!(zbus::Message: TryFrom<$ufet>);
891 };
892}
893
894macro_rules! impl_msg_conversion_ext_for_target_type_with_specified_body_type {
917 (target: $target_type:ty, body: $body_type:ty) => {
918 #[cfg(feature = "zbus")]
919 impl<'a> crate::events::MessageConversionExt<'a, $body_type> for $target_type {
920 fn try_from_message(msg: &zbus::Message, hdr: &Header) -> Result<Self, AtspiError> {
921 use crate::events::MessageConversionExt;
922 <Self as MessageConversionExt<$body_type>>::validate_interface(hdr)?;
923 <Self as MessageConversionExt<$body_type>>::validate_member(hdr)?;
924 <Self as MessageConversionExt<$body_type>>::validate_body(msg)?;
925 <Self as MessageConversion<'a>>::from_message_unchecked(msg, hdr)
926 }
927 }
928 };
929}
930
931macro_rules! impl_msg_conversion_ext_for_target_type {
967 ($target_type:ty) => {
968 #[cfg(feature = "zbus")]
969 impl<'msg> crate::events::MessageConversionExt<'msg, crate::events::EventBody<'msg>> for $target_type {
970 fn try_from_message(msg: &'msg zbus::Message, header: &Header) -> Result<Self, AtspiError> {
971 use zvariant::Type;
972 use crate::events::traits::MessageConversion;
973 Self::validate_interface(header)?;
974 Self::validate_member(header)?;
975
976 let item = ObjectRefOwned::try_from(header)?;
977 let msg_body = msg.body();
978 let signature = msg_body.signature();
979
980 if signature == crate::events::EventBodyOwned::SIGNATURE
981 || signature == crate::events::EventBodyQtOwned::SIGNATURE
982 {
983 Self::from_message_unchecked_parts(item.into_inner(), msg_body)
984 } else {
985 Err(AtspiError::SignatureMatch(format!(
986 "The message signature {} does not match a valid signal body signature: {} or {}",
987 msg.body().signature(),
988 crate::events::EventBodyOwned::SIGNATURE,
989 crate::events::EventBodyQtOwned::SIGNATURE,
990 )))
991 }
992 }
993 }
994 };
995}
996
997#[cfg(feature = "wrappers")]
998macro_rules! impl_tryfrommessage_for_event_wrapper {
1024 ($wrapper:ty) => {
1025 #[cfg(feature = "zbus")]
1026 impl crate::events::traits::TryFromMessage for $wrapper {
1027 fn try_from_message(msg: &zbus::Message) -> Result<$wrapper, AtspiError> {
1028 use crate::events::traits::EventWrapperMessageConversion;
1029
1030 let header = msg.header();
1031 let interface = header.interface().ok_or(AtspiError::MissingInterface)?;
1032 if interface != Self::DBUS_INTERFACE {
1033 return Err(AtspiError::InterfaceMatch(format!(
1034 "Interface {} does not match require interface for event: {}",
1035 interface,
1036 Self::DBUS_INTERFACE
1037 )));
1038 }
1039 Self::try_from_message_interface_checked(msg, &header)
1040 }
1041 }
1042 };
1043}
1044
1045macro_rules! impl_msg_conversion_for_types_built_from_object_ref {
1081 ($($type:ty),*) => {
1082 $(
1083 #[cfg(feature = "zbus")]
1084 impl crate::events::MessageConversion<'_> for $type {
1085 type Body<'msg> = crate::events::EventBody<'msg>;
1086
1087 fn from_message_unchecked_parts(
1088 obj_ref: crate::object_ref::ObjectRef<'_>,
1089 _body: zbus::message::Body,
1090 ) -> Result<Self, AtspiError> {
1091 Ok(obj_ref.into())
1092 }
1093
1094 fn from_message_unchecked(_: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
1095 let obj_ref: ObjectRefOwned = header.try_into()?;
1096 Ok( Self { item: obj_ref })
1097 }
1098
1099 fn body(&self) -> Self::Body<'_> {
1100 crate::events::EventBodyOwned::default().into()
1101 }
1102 }
1103 )*
1104 };
1105}
1106
1107macro_rules! impl_member_interface_registry_string_and_match_rule_for_event {
1141 ($target_type:ty, $member_str:literal, $interface_str:literal, $registry_str:literal, $match_rule_str:literal) => {
1142 impl crate::events::DBusMember for $target_type {
1143 const DBUS_MEMBER: &'static str = $member_str;
1144 }
1145 impl crate::events::DBusInterface for $target_type {
1146 const DBUS_INTERFACE: &'static str = $interface_str;
1147 }
1148 impl crate::events::DBusMatchRule for $target_type {
1149 const MATCH_RULE_STRING: &'static str = $match_rule_str;
1150 }
1151 impl crate::events::RegistryEventString for $target_type {
1152 const REGISTRY_EVENT_STRING: &'static str = $registry_str;
1153 }
1154 impl crate::events::DBusProperties for $target_type {}
1155 };
1156}
1157
1158macro_rules! impl_event_type_properties_for_event {
1185 ($target_type:ty) => {
1186 impl crate::events::EventTypeProperties for $target_type {
1187 fn member(&self) -> &'static str {
1188 Self::DBUS_MEMBER
1189 }
1190
1191 fn interface(&self) -> &'static str {
1192 Self::DBUS_INTERFACE
1193 }
1194
1195 fn registry_string(&self) -> &'static str {
1196 Self::REGISTRY_EVENT_STRING
1197 }
1198
1199 fn match_rule(&self) -> &'static str {
1200 Self::MATCH_RULE_STRING
1201 }
1202 }
1203 };
1204}