1macro_rules! impl_event_properties {
21 ($type:ty) => {
22 impl crate::EventProperties for $type {
23 fn sender(&self) -> zbus_names::UniqueName<'_> {
24 self.item.name.as_ref()
25 }
26 fn path(&self) -> zvariant::ObjectPath<'_> {
27 self.item.path.as_ref()
28 }
29 }
30 };
31}
32
33macro_rules! impl_from_object_ref {
50 ($type:ty) => {
51 impl From<crate::ObjectRef> for $type {
52 fn from(obj_ref: crate::ObjectRef) -> Self {
53 Self { item: obj_ref }
54 }
55 }
56 };
57}
58
59#[cfg(feature = "wrappers")]
60macro_rules! impl_from_interface_event_enum_for_event {
76 ($outer_type:ty, $outer_variant:path) => {
77 #[cfg(feature = "wrappers")]
78 impl From<$outer_type> for Event {
79 fn from(event_variant: $outer_type) -> Event {
80 $outer_variant(event_variant.into())
81 }
82 }
83 };
84}
85
86#[cfg(feature = "wrappers")]
87macro_rules! impl_try_from_event_for_interface_enum {
108 ($outer_type:ty, $outer_variant:path) => {
109 impl TryFrom<Event> for $outer_type {
110 type Error = AtspiError;
111 fn try_from(generic_event: Event) -> Result<$outer_type, Self::Error> {
112 if let $outer_variant(event_type) = generic_event {
113 Ok(event_type)
114 } else {
115 Err(AtspiError::Conversion("Invalid type"))
116 }
117 }
118 }
119 };
120}
121
122#[cfg(feature = "wrappers")]
123macro_rules! impl_from_user_facing_event_for_interface_event_enum {
140 ($inner_type:ty, $outer_type:ty, $inner_variant:path) => {
141 impl From<$inner_type> for $outer_type {
142 fn from(specific_event: $inner_type) -> $outer_type {
143 $inner_variant(specific_event)
144 }
145 }
146 };
147}
148
149#[cfg(feature = "wrappers")]
150macro_rules! impl_from_user_facing_type_for_event_enum {
170 ($inner_type:ty, $outer_variant:path) => {
171 #[cfg(feature = "wrappers")]
172 impl From<$inner_type> for Event {
173 fn from(event_variant: $inner_type) -> Event {
174 $outer_variant(event_variant.into())
175 }
176 }
177 };
178}
179
180#[cfg(feature = "wrappers")]
181macro_rules! impl_try_from_event_for_user_facing_type {
211 ($inner_type:ty, $inner_variant:path, $outer_variant:path) => {
212 #[cfg(feature = "wrappers")]
213 impl TryFrom<crate::Event> for $inner_type {
214 type Error = AtspiError;
215 fn try_from(generic_event: crate::Event) -> Result<$inner_type, Self::Error> {
216 if let $outer_variant($inner_variant(specific_event)) = generic_event {
217 Ok(specific_event)
218 } else {
219 Err(AtspiError::Conversion("Invalid type"))
220 }
221 }
222 }
223 };
224}
225
226macro_rules! impl_to_dbus_message {
250 ($type:ty) => {
251 #[cfg(feature = "zbus")]
252 impl TryFrom<$type> for zbus::Message {
253 type Error = AtspiError;
254 fn try_from(event: $type) -> Result<Self, Self::Error> {
255 use crate::events::{DBusInterface, DBusMember, MessageConversion};
256 Ok(zbus::Message::signal(
257 event.path(),
258 <$type as DBusInterface>::DBUS_INTERFACE,
259 <$type as DBusMember>::DBUS_MEMBER,
260 )?
261 .sender(event.sender().to_string())?
262 .build(&event.body())?)
263 }
264 }
265 };
266}
267
268macro_rules! impl_from_dbus_message {
292 ($type:ty) => {
293 impl_from_dbus_message!($type, Auto);
294 };
295
296 ($type:ty, Auto) => {
297 #[cfg(feature = "zbus")]
298 impl<'msg> TryFrom<&'msg zbus::Message> for $type {
299 type Error = AtspiError;
300 fn try_from(msg: &'msg zbus::Message) -> Result<Self, Self::Error> {
301 use crate::events::{EventBody, EventBodyQtBorrowed};
302 use crate::events::traits::{MessageConversion, MessageConversionExt};
303 use zvariant::Type;
304 use crate::ObjectRef;
305
306 let hdr = msg.header();
307 <Self as MessageConversionExt<<Self as MessageConversion>::Body<'_>>>::validate_interface(&hdr)?;
308 <Self as MessageConversionExt<<Self as MessageConversion>::Body<'_>>>::validate_member(&hdr)?;
309 let item = ObjectRef::try_from(&hdr)?;
310
311 let body = msg.body();
312 let signature = body.signature();
313
314 if signature == EventBody::SIGNATURE || signature == EventBodyQtBorrowed::SIGNATURE {
315 Ok(Self::from_message_unchecked_parts(item, body)?)
316 } else {
317 Err(AtspiError::SignatureMatch(format!(
318 "signature mismatch: expected: {}, signal body: {}",
319 msg.body().signature(),
320 <Self as MessageConversion>::Body::SIGNATURE,
321 )))
322 }
323 }
324 }
325 };
326
327 ($type:ty, Explicit) => {
328 #[cfg(feature = "zbus")]
329 impl TryFrom<&zbus::Message> for $type {
330 type Error = crate::AtspiError;
331 fn try_from(msg: &zbus::Message) -> Result<Self, Self::Error> {
332 let hdr = msg.header();
333 <$type as crate::events::MessageConversionExt<<$type as MessageConversion>::Body<'_>>>::try_from_message(msg, &hdr)
334 }
335 }
336 };
337}
338
339#[cfg(test)]
351macro_rules! generic_event_test_case {
352 ($type:ty) => {
353 #[test]
354 fn generic_event_uses() {
355 use crate::events::traits::MessageConversion;
356 let struct_event = <$type>::default();
357 assert_eq!(struct_event.path().as_str(), "/org/a11y/atspi/accessible/null");
358 assert_eq!(struct_event.sender().as_str(), ":0.0");
359 let body = struct_event.body();
360 let body2 = Message::method_call(
361 struct_event.path().as_str(),
362 <$type as crate::events::DBusMember>::DBUS_MEMBER,
363 )
364 .unwrap()
365 .sender(struct_event.sender().as_str())
366 .unwrap()
367 .build(&(body,))
368 .unwrap();
369 let header = body2.header();
370 let build_struct = <$type>::from_message_unchecked(&body2, &header)
371 .expect("<$type as Default>'s parts should build a valid ObjectRef");
372 assert_eq!(struct_event, build_struct);
373 }
374 };
375}
376
377#[cfg(test)]
388macro_rules! event_has_matching_xml_definition {
389 ($type:ty) => {
390 #[test]
391 fn event_has_matching_xml_definition() {
392 use zbus_xml;
393 use crate::events::{DBusInterface, DBusMember};
394
395 let fname = match <$type>::DBUS_INTERFACE.split(".").last().expect("Has last section") {
396 "Cache" => "xml/Cache.xml",
397 "Socket" => "xml/Socket.xml",
398 "Registry" => "xml/Registry.xml",
399 _ => "xml/Event.xml",
400 };
401 let reader = std::fs::File::open(fname).expect("Valid file path!");
402 let xml = zbus_xml::Node::from_reader(reader).expect("Valid DBus XML file!");
403 let Some(interface) = xml.interfaces().iter().find(|int| int.name() == <$type>::DBUS_INTERFACE) else {
404 let possible_names: Vec<String> = xml.interfaces().iter().map(|int| int.name().as_str().to_string()).collect();
405 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);
406 };
407 let Some(_member) = interface.signals().iter().find(|mem| mem.name() == <$type>::DBUS_MEMBER) else {
408 let possible_names: Vec<String> = interface.signals().iter().map(|mem| mem.name().as_str().to_string()).collect();
409 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);
410 };
411 }
412 };
413}
414
415#[cfg(test)]
416macro_rules! zbus_message_qtspi_test_case {
417 ($type:ty, Auto) => {
418 #[cfg(feature = "zbus")]
419 #[test]
420 fn zbus_message_conversion_qtspi() {
421 use crate::events::EventTypeProperties;
422 use crate::events::MessageConversion;
423
424 let ev = <$type>::default();
427 let qt: crate::events::EventBodyQtOwned = ev.body().into();
428 let msg = zbus::Message::signal(
429 ev.path(),
430 ev.interface(),
431 ev.member(),
432 )
433 .unwrap()
434 .sender(":0.0")
435 .unwrap()
436 .build(&(qt,))
437 .unwrap();
438 <$type>::try_from(&msg).expect("Should be able to use an EventBodyQtOwned for any type whose BusProperties::Body = EventBodyOwned");
439 }
440 #[cfg(feature = "zbus")]
441 #[test]
442 fn zbus_message_conversion_qtspi_event_enum() {
443 use crate::events::EventTypeProperties;
444 use crate::events::MessageConversion;
445 use crate::Event;
446
447
448 let ev = <$type>::default();
451 let qt: crate::events::EventBodyQtOwned = ev.body().into();
452 let msg = zbus::Message::signal(
453 ev.path(),
454 ev.interface(),
455 ev.member(),
456 )
457 .unwrap()
458 .sender(":0.0")
459 .unwrap()
460 .build(&(qt,))
461 .unwrap();
462 assert_matches!(Event::try_from(&msg), Ok(_));
463 }
464 };
465 ($type:ty, Explicit) => {};
466}
467
468#[cfg(test)]
474macro_rules! zbus_message_test_case {
475 ($type:ty) => {
476 zbus_message_test_case!($type, Auto);
477 };
478 ($type:ty, $extra:tt) => {
479 zbus_message_qtspi_test_case!($type, $extra);
480 #[cfg(feature = "zbus")]
481 #[test]
482 fn zbus_msg_conversion_to_specific_event_type() {
483 let struct_event = <$type>::default();
484 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 .");
485
486 let struct_event_back =
487 <$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.");
488 assert_eq!(struct_event, struct_event_back, "Events converted into a message and back must be the same");
489 }
490
491 #[cfg(feature = "zbus")]
492 #[test]
493 fn zbus_msg_conversion_to_event_enum_type() {
494 let struct_event = <$type>::default();
495 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.");
496 let event_enum_back =
497 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.");
498 let event_enum: crate::Event = struct_event.into();
499 assert_eq!(event_enum, event_enum_back);
500 }
501 #[cfg(feature = "zbus")]
504 #[test]
505 fn zbus_msg_conversion_failure_fake_msg() -> () {
506 let fake_msg = zbus::Message::signal(
507 "/org/a11y/sixtynine/fourtwenty",
508 "org.a11y.atspi.technically.valid",
509 "MadeUpMember",
510 )
511 .unwrap()
512 .sender(":0.0")
513 .unwrap()
514 .build(&())
515 .unwrap();
516 let event = <$type>::try_from(&fake_msg);
517 assert_matches!(event, Err(_), "This conversion should fail");
518 }
519
520 #[cfg(feature = "zbus")]
521 #[test]
522 fn zbus_msg_conversion_validated_message_with_body() -> () {
523 use crate::events::MessageConversion;
524
525 let fake_msg = zbus::Message::signal(
526 "/org/a11y/sixtynine/fourtwenty",
527 "org.a11y.atspi.technically.valid",
528 "MadeUpMember",
529 )
530 .unwrap()
531 .sender(":0.0")
532 .unwrap()
533 .build(&<$type>::default().body())
534 .unwrap();
535 let hdr = fake_msg.header();
536 let event = <$type>::from_message_unchecked(&fake_msg, &hdr);
537 event.expect("The from_message_unchecked function should work, despite mismatching interface and member");
538 }
539
540 #[cfg(feature = "zbus")]
541 #[test]
542 fn zbus_msg_conversion_failure_correct_interface() -> () {
543 let fake_msg = zbus::Message::signal(
544 "/org/a11y/sixtynine/fourtwenty",
545 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
546 "MadeUpMember",
547 )
548 .unwrap()
549 .sender(":0.0")
550 .unwrap()
551 .build(&())
552 .unwrap();
553 let event = <$type>::try_from(&fake_msg);
554 assert_matches!(event, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
555 }
556
557 #[cfg(feature = "zbus")]
558 #[test]
559 fn zbus_msg_conversion_failure_correct_interface_and_member() -> () {
560 let fake_msg = zbus::Message::signal(
561 "/org/a11y/sixtynine/fourtwenty",
562 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
563 <$type as crate::events::DBusMember>::DBUS_MEMBER,
564 )
565 .unwrap()
566 .sender(":0.0")
567 .unwrap()
568 .build(&())
569 .unwrap();
570 let event = <$type>::try_from(&fake_msg);
571 assert_matches!(event, Err(AtspiError::SignatureMatch(_)), "Wrong kind of error");
572 }
573
574 #[cfg(feature = "zbus")]
575 #[test]
576 fn zbus_msg_conversion_failure_correct_interface_and_member_invalid_body() -> () {
577 let invalid_body: (i32, u64, String, String) = (0, 0, String::new(), String::new());
579 let fake_msg = zbus::Message::signal(
580 "/org/a11y/sixtynine/fourtwenty",
581 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
582 <$type as crate::events::DBusMember>::DBUS_MEMBER,
583 )
584 .unwrap()
585 .sender(":0.0")
586 .unwrap()
587 .build(&invalid_body)
588 .unwrap();
589 let event = <$type>::try_from(&fake_msg);
590 assert_matches!(event, Err(AtspiError::SignatureMatch(_)), "Wrong kind of error");
591 }
592
593 #[cfg(feature = "zbus")]
594 #[test]
595 fn zbus_msg_conversion_failure_correct_body() -> () {
596 use crate::events::MessageConversion;
597 let fake_msg = zbus::Message::signal(
598 "/org/a11y/sixtynine/fourtwenty",
599 "org.a11y.atspi.accessible.technically.valid",
600 "FakeMember",
601 )
602 .unwrap()
603 .sender(":0.0")
604 .unwrap()
605 .build(&<$type>::default().body())
606 .unwrap();
607 let event = <$type>::try_from(&fake_msg);
608 assert_matches!(event, Err(_));
609 }
610
611 #[cfg(feature = "zbus")]
612 #[test]
613 fn zbus_msg_conversion_failure_correct_body_and_member() -> () {
614 use crate::events::MessageConversion;
615
616 let fake_msg = zbus::Message::signal(
617 "/org/a11y/sixtynine/fourtwenty",
618 "org.a11y.atspi.accessible.technically.valid",
619 <$type as crate::events::DBusMember>::DBUS_MEMBER,
620 )
621 .unwrap()
622 .sender(":0.0")
623 .unwrap()
624 .build(&<$type>::default().body())
625 .unwrap();
626 let event = <$type>::try_from(&fake_msg);
627 assert_matches!(event, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
628 }
629 #[cfg(feature = "zbus")]
630 #[test]
631 fn zbus_msg_conversion_failure_correct_body_and_interface() -> () {
632 use crate::events::MessageConversion;
633
634 let fake_msg = zbus::Message::signal(
635 "/org/a11y/sixtynine/fourtwenty",
636 <$type as crate::events::DBusInterface>::DBUS_INTERFACE,
637 "MadeUpMember",
638 )
639 .unwrap()
640 .sender(":0.0")
641 .unwrap()
642 .build(&<$type>::default().body())
643 .unwrap();
644 let event = <$type>::try_from(&fake_msg);
645 assert_matches!(event, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
646 }
647 };
648}
649
650#[cfg(feature = "wrappers")]
651macro_rules! event_wrapper_test_cases {
672 ($iface_enum:ty, $ufet:ty) => {
674 #[cfg(test)]
675 #[rename_item::rename(name($iface_enum), prefix = "events_tests_", case = "snake")]
676 mod foo {
677 use super::{$ufet, $iface_enum, AtspiError, Event, MessageConversion};
678
679 use assert_matches::assert_matches;
681
682 #[test]
683 fn into_and_try_from_user_facing_event() {
684 let sub_type = <$ufet>::default();
686
687 let mod_type = <$iface_enum>::from(sub_type);
689 let hint_iface = "Check macro `impl_from_user_facing_event_for_interface_event_enum!`";
690
691 let event = Event::from(mod_type.clone());
693 let hint_event = "Check macro `impl_from_interface_event_enum_for_event!`";
694
695 let hint_event_try = "Check macro `impl_try_from_event_for_interface_enum!`";
697 let mod_type2 = <$iface_enum>::try_from(event.clone())
698 .expect("Should convert outer `Event` enum into interface enum. hints: {hint_event} and {hint_event_try}");
699
700 assert_eq!(
701 mod_type, mod_type2,
702 "Interface enums should match. hint: {hint_iface}, {hint_event} and {hint_event_try}"
703 );
704 }
705
706 #[cfg(feature = "zbus")]
707 #[test]
708 fn zbus_msg_invalid_interface() {
709 let fake_msg = zbus::Message::signal(
710 "/org/a11y/sixtynine/fourtwenty",
711 "org.a11y.atspi.technically.valid.lol",
712 <$ufet as crate::events::DBusMember>::DBUS_MEMBER,
713 )
714 .unwrap()
715 .sender(":0.0")
716 .unwrap()
717 .build(&<$ufet>::default().body())
718 .unwrap();
719
720 let mod_type = <$iface_enum>::try_from(&fake_msg);
733 let event_type = Event::try_from(&fake_msg);
734
735 assert_matches!(mod_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
736 assert_matches!(event_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
737 }
738
739 #[cfg(feature = "zbus")]
740 #[test]
741 fn zbus_msg_invalid_member() {
742 let fake_msg = zbus::Message::signal(
743 "/org/a11y/sixtynine/fourtwenty",
744 <$ufet as crate::events::DBusInterface>::DBUS_INTERFACE,
745 "FakeFunctionLol",
746 )
747 .unwrap()
748 .sender(":0.0")
749 .unwrap()
750 .build(&<$ufet>::default().body())
751 .unwrap();
752 let mod_type = <$iface_enum>::try_from(&fake_msg);
754 assert_matches!(mod_type, Err(AtspiError::MemberMatch(_)), "Wrong kind of error");
755 }
756 #[cfg(feature = "zbus")]
757 #[test]
758 fn zbus_msg_invalid_member_and_interface() {
759 let fake_msg = zbus::Message::signal(
760 "/org/a11y/sixtynine/fourtwenty",
761 "org.a11y.atspi.technically.allowed",
762 "FakeFunctionLol",
763 )
764 .unwrap()
765 .sender(":0.0")
766 .unwrap()
767 .build(&<$ufet>::default().body())
768 .unwrap();
769 let mod_type = <$iface_enum>::try_from(&fake_msg);
771
772 assert_matches!(mod_type, Err(AtspiError::InterfaceMatch(_)), "Wrong kind of error");
774 }
775
776 #[cfg(feature = "zbus")]
777 #[test]
778 fn zbus_msg_conversion() {
779 let valid_msg = zbus::Message::signal(
780 "/org/a11y/sixtynine/fourtwenty",
781 <$ufet as crate::events::DBusInterface>::DBUS_INTERFACE,
782 <$ufet as crate::events::DBusMember>::DBUS_MEMBER,
783 )
784 .unwrap()
785 .sender(":0.0")
786 .unwrap()
787 .build(&<$ufet>::default().body())
788 .unwrap();
789 let mod_type = <$iface_enum>::try_from(&valid_msg);
791 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.");
792 }
793
794
795 }
796 };
797}
798
799macro_rules! event_test_cases {
800 ($ufet:ty) => {
801 event_test_cases!($ufet, Auto);
802 };
803 ($ufet:ty, $qt:tt) => {
804 #[cfg(test)]
805 #[rename_item::rename(name($ufet), prefix = "event_tests_", case = "snake")]
806 mod foo {
807 use super::{$ufet, AtspiError, EventProperties };
808 use crate::events::traits::EventTypeProperties;
809 use zbus::Message;
810 use crate::Event;
811
812 use assert_matches::assert_matches;
814
815 #[test]
816 #[cfg(feature = "wrappers")]
817 fn event_enum_conversion() {
818 let event_struct = <$ufet>::default();
819 let event_enum = Event::from(event_struct.clone());
820 let event_struct_back = <$ufet>::try_from(event_enum)
821 .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");
822 assert_eq!(event_struct, event_struct_back);
823 }
824
825 #[test]
826 #[cfg(feature = "wrappers")]
827 fn event_enum_transparency_test_case() {
828 let specific_event = <$ufet>::default();
829
830 let generic_event = Event::from(specific_event.clone());
831 let hint = "Check macro `impl_from_user_facing_type_for_event_enum!`.";
832
833 assert_eq!(
834 specific_event.member(),
835 generic_event.member(),
836 "DBus members do not match. hint: {hint}"
837 );
838 assert_eq!(
839 specific_event.interface(),
840 generic_event.interface(),
841 "DBus interfaces do not match. hint: {hint}"
842 );
843 assert_eq!(
844 specific_event.registry_string(),
845 generic_event.registry_string(),
846 "Registry strings do not match. hint: {hint}"
847 );
848 assert_eq!(
849 specific_event.match_rule(),
850 generic_event.match_rule(),
851 "Match rule strings do not match. hint: {hint}"
852 );
853 assert_eq!(specific_event.path(), generic_event.path(), "Paths do not match. hint: {hint}");
854 assert_eq!(specific_event.sender(), generic_event.sender(), "Senders do not match. hint: {hint}");
855 }
856
857 zbus_message_test_case!($ufet, $qt);
858 event_has_matching_xml_definition!($ufet);
859 generic_event_test_case!($ufet);
860 }
861 assert_impl_all!(
862 $ufet: Clone,
863 std::fmt::Debug,
864 serde::Serialize,
865 serde::Deserialize<'static>,
866 Default,
867 PartialEq,
868 Eq,
869 std::hash::Hash,
870 crate::events::traits::EventProperties,
871 crate::events::traits::EventTypeProperties,
872 crate::events::traits::DBusInterface,
873 crate::events::traits::DBusMember,
874 crate::events::traits::DBusMatchRule,
875 crate::events::traits::RegistryEventString
876 );
877
878 #[cfg(feature = "zbus")]
879 assert_impl_all!(zbus::Message: TryFrom<$ufet>);
880 };
881}
882
883macro_rules! impl_msg_conversion_ext_for_target_type_with_specified_body_type {
906 (target: $target_type:ty, body: $body_type:ty) => {
907 #[cfg(feature = "zbus")]
908 impl<'a> crate::events::MessageConversionExt<'a, $body_type> for $target_type {
909 fn try_from_message(msg: &zbus::Message, hdr: &Header) -> Result<Self, AtspiError> {
910 use crate::events::MessageConversionExt;
911 <Self as MessageConversionExt<$body_type>>::validate_interface(hdr)?;
912 <Self as MessageConversionExt<$body_type>>::validate_member(hdr)?;
913 <Self as MessageConversionExt<$body_type>>::validate_body(msg)?;
914 <Self as MessageConversion<'a>>::from_message_unchecked(msg, hdr)
915 }
916 }
917 };
918}
919
920macro_rules! impl_msg_conversion_ext_for_target_type {
956 ($target_type:ty) => {
957 #[cfg(feature = "zbus")]
958 impl<'msg> crate::events::MessageConversionExt<'msg, crate::events::EventBody<'msg>> for $target_type {
959 fn try_from_message(msg: &'msg zbus::Message, header: &Header) -> Result<Self, AtspiError> {
960 use zvariant::Type;
961 use crate::events::traits::MessageConversion;
962 Self::validate_interface(header)?;
963 Self::validate_member(header)?;
964
965 let item = crate::events::ObjectRef::try_from(header)?;
966 let msg_body = msg.body();
967 let signature = msg_body.signature();
968
969 if signature == crate::events::EventBodyOwned::SIGNATURE
970 || signature == crate::events::EventBodyQtOwned::SIGNATURE
971 {
972 Self::from_message_unchecked_parts(item, msg_body)
973 } else {
974 Err(AtspiError::SignatureMatch(format!(
975 "The message signature {} does not match a valid signal body signature: {} or {}",
976 msg.body().signature(),
977 crate::events::EventBodyOwned::SIGNATURE,
978 crate::events::EventBodyQtOwned::SIGNATURE,
979 )))
980 }
981 }
982 }
983 };
984}
985
986#[cfg(feature = "wrappers")]
987macro_rules! impl_tryfrommessage_for_event_wrapper {
1013 ($wrapper:ty) => {
1014 #[cfg(feature = "zbus")]
1015 impl crate::events::traits::TryFromMessage for $wrapper {
1016 fn try_from_message(msg: &zbus::Message) -> Result<$wrapper, AtspiError> {
1017 use crate::events::traits::EventWrapperMessageConversion;
1018
1019 let header = msg.header();
1020 let interface = header.interface().ok_or(AtspiError::MissingInterface)?;
1021 if interface != Self::DBUS_INTERFACE {
1022 return Err(AtspiError::InterfaceMatch(format!(
1023 "Interface {} does not match require interface for event: {}",
1024 interface,
1025 Self::DBUS_INTERFACE
1026 )));
1027 }
1028 Self::try_from_message_interface_checked(msg, &header)
1029 }
1030 }
1031 };
1032}
1033
1034macro_rules! impl_msg_conversion_for_types_built_from_object_ref {
1070 ($($type:ty),*) => {
1071 $(
1072 #[cfg(feature = "zbus")]
1073 impl crate::events::MessageConversion<'_> for $type {
1074 type Body<'msg> = crate::events::EventBody<'msg>;
1075
1076 fn from_message_unchecked_parts(
1077 obj_ref: crate::events::ObjectRef,
1078 _body: zbus::message::Body,
1079 ) -> Result<Self, AtspiError> {
1080 Ok(obj_ref.into())
1081 }
1082
1083 fn from_message_unchecked(_: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
1084 let obj_ref: crate::events::ObjectRef = header.try_into()?;
1085 Ok(obj_ref.into())
1086 }
1087
1088 fn body(&self) -> Self::Body<'_> {
1089 crate::events::EventBodyOwned::default().into()
1090 }
1091 }
1092 )*
1093 };
1094}
1095
1096macro_rules! impl_member_interface_registry_string_and_match_rule_for_event {
1130 ($target_type:ty, $member_str:literal, $interface_str:literal, $registry_str:literal, $match_rule_str:literal) => {
1131 impl crate::events::DBusMember for $target_type {
1132 const DBUS_MEMBER: &'static str = $member_str;
1133 }
1134 impl crate::events::DBusInterface for $target_type {
1135 const DBUS_INTERFACE: &'static str = $interface_str;
1136 }
1137 impl crate::events::DBusMatchRule for $target_type {
1138 const MATCH_RULE_STRING: &'static str = $match_rule_str;
1139 }
1140 impl crate::events::RegistryEventString for $target_type {
1141 const REGISTRY_EVENT_STRING: &'static str = $registry_str;
1142 }
1143 impl crate::events::DBusProperties for $target_type {}
1144 };
1145}
1146
1147macro_rules! impl_event_type_properties_for_event {
1174 ($target_type:ty) => {
1175 impl crate::events::EventTypeProperties for $target_type {
1176 fn member(&self) -> &'static str {
1177 Self::DBUS_MEMBER
1178 }
1179
1180 fn interface(&self) -> &'static str {
1181 Self::DBUS_INTERFACE
1182 }
1183
1184 fn registry_string(&self) -> &'static str {
1185 Self::REGISTRY_EVENT_STRING
1186 }
1187
1188 fn match_rule(&self) -> &'static str {
1189 Self::MATCH_RULE_STRING
1190 }
1191 }
1192 };
1193}