atspi_common/
macros.rs
1#[macro_export]
2
3macro_rules! impl_from_interface_event_enum_for_event {
19 ($outer_type:ty, $outer_variant:path) => {
20 impl From<$outer_type> for Event {
21 fn from(event_variant: $outer_type) -> Event {
22 $outer_variant(event_variant.into())
23 }
24 }
25 };
26}
27
28macro_rules! impl_try_from_event_for_user_facing_event_type {
49 ($outer_type:ty, $outer_variant:path) => {
50 impl TryFrom<Event> for $outer_type {
51 type Error = AtspiError;
52 fn try_from(generic_event: Event) -> Result<$outer_type, Self::Error> {
53 if let $outer_variant(event_type) = generic_event {
54 Ok(event_type)
55 } else {
56 Err(AtspiError::Conversion("Invalid type"))
57 }
58 }
59 }
60 };
61}
62
63macro_rules! impl_from_user_facing_event_for_interface_event_enum {
80 ($inner_type:ty, $outer_type:ty, $inner_variant:path) => {
81 impl From<$inner_type> for $outer_type {
82 fn from(specific_event: $inner_type) -> $outer_type {
83 $inner_variant(specific_event)
84 }
85 }
86 };
87}
88
89macro_rules! impl_from_user_facing_type_for_event_enum {
109 ($inner_type:ty, $outer_variant:path) => {
110 impl From<$inner_type> for Event {
111 fn from(event_variant: $inner_type) -> Event {
112 $outer_variant(event_variant.into())
113 }
114 }
115 };
116}
117
118macro_rules! impl_try_from_event_for_user_facing_type {
141 ($inner_type:ty, $inner_variant:path, $outer_variant:path) => {
142 impl TryFrom<Event> for $inner_type {
143 type Error = AtspiError;
144 fn try_from(generic_event: Event) -> Result<$inner_type, Self::Error> {
145 if let $outer_variant($inner_variant(specific_event)) = generic_event {
146 Ok(specific_event)
147 } else {
148 Err(AtspiError::Conversion("Invalid type"))
149 }
150 }
151 }
152 };
153}
154
155macro_rules! impl_to_dbus_message {
179 ($type:ty) => {
180 #[cfg(feature = "zbus")]
181 impl TryFrom<$type> for zbus::Message {
182 type Error = AtspiError;
183 fn try_from(event: $type) -> Result<Self, Self::Error> {
184 Ok(zbus::MessageBuilder::signal(
185 event.path(),
186 <$type as GenericEvent>::DBUS_INTERFACE,
187 <$type as GenericEvent>::DBUS_MEMBER,
188 )?
189 .sender(event.sender())?
190 .build(&event.body())?)
191 }
192 }
193 };
194}
195
196macro_rules! impl_from_dbus_message {
224 ($type:ty) => {
225 #[cfg(feature = "zbus")]
226 impl TryFrom<&zbus::Message> for $type {
227 type Error = AtspiError;
228 fn try_from(msg: &zbus::Message) -> Result<Self, Self::Error> {
229 if msg.interface().ok_or(AtspiError::MissingInterface)?
230 != <$type as GenericEvent>::DBUS_INTERFACE
231 {
232 return Err(AtspiError::InterfaceMatch(format!(
233 "The interface {} does not match the signal's interface: {}",
234 msg.interface().unwrap(),
235 <$type as GenericEvent>::DBUS_INTERFACE
236 )));
237 }
238 if msg.member().ok_or(AtspiError::MissingMember)? != <$type>::DBUS_MEMBER {
239 return Err(AtspiError::MemberMatch(format!(
240 "The member {} does not match the signal's member: {}",
241 msg.member().unwrap(),
243 <$type as GenericEvent>::DBUS_MEMBER
244 )));
245 }
246 <$type>::build(msg.try_into()?, msg.body::<<$type as GenericEvent>::Body>()?)
247 }
248 }
249 };
250}
251
252#[cfg(test)]
260macro_rules! generic_event_test_case {
261 ($type:ty) => {
262 #[test]
263 fn generic_event_uses() {
264 let struct_event = <$type>::default();
265 assert_eq!(struct_event.path().as_str(), "/org/a11y/atspi/accessible/null");
266 assert_eq!(struct_event.sender().as_str(), ":0.0");
267 let item = struct_event.item.clone();
268 let body = struct_event.body();
269 let build_struct = <$type>::build(item, body).expect("Could not build type from parts");
270 assert_eq!(struct_event, build_struct);
271 }
272 };
273}
274
275#[cfg(test)]
282macro_rules! event_enum_test_case {
283 ($type:ty) => {
284 #[test]
285 fn event_enum_conversion() {
286 let struct_event = <$type>::default();
287 let event = Event::from(struct_event.clone());
288 let struct_event_back = <$type>::try_from(event)
289 .expect("Could not convert from `Event` back to specific event type");
290 assert_eq!(struct_event, struct_event_back);
291 }
292 };
293}
294
295#[cfg(test)]
296macro_rules! zbus_message_test_case {
297 ($type:ty) => {
298 #[cfg(feature = "zbus")]
299 #[test]
300 fn zbus_msg_conversion_to_specific_event_type() {
301 let struct_event = <$type>::default();
302 let msg: zbus::Message = zbus::Message::try_from(struct_event.clone())
303 .expect("Could not convert event into a message");
304 let struct_event_back =
305 <$type>::try_from(&msg).expect("Could not convert message into an event");
306 assert_eq!(struct_event, struct_event_back);
307 }
308 #[cfg(feature = "zbus")]
309 #[test]
310 fn zbus_msg_conversion_to_event_enum_type() {
311 let struct_event = <$type>::default();
312 let msg: zbus::Message = zbus::Message::try_from(struct_event.clone())
313 .expect("Could not convert event into a message");
314 let event_enum_back =
315 Event::try_from(&msg).expect("Could not convert message into an event");
316 let event_enum: Event = struct_event.into();
317 assert_eq!(event_enum, event_enum_back);
318 }
319 #[cfg(feature = "zbus")]
322 #[test]
323 #[should_panic(expected = "should panic")]
324 fn zbus_msg_conversion_failure_fake_msg() -> () {
325 let fake_msg = zbus::MessageBuilder::signal(
326 "/org/a11y/sixtynine/fourtwenty",
327 "org.a11y.atspi.technically.valid",
328 "MadeUpMember",
329 )
330 .unwrap()
331 .sender(":0.0")
332 .unwrap()
333 .build(&())
334 .unwrap();
335 let event = <$type>::try_from(&fake_msg);
336 event.expect("This should panic! Invalid event.");
337 }
338 #[cfg(feature = "zbus")]
339 #[test]
340 #[should_panic(expected = "should panic")]
341 fn zbus_msg_conversion_failure_correct_interface() -> () {
342 let fake_msg = zbus::MessageBuilder::signal(
343 "/org/a11y/sixtynine/fourtwenty",
344 <$type as GenericEvent>::DBUS_INTERFACE,
345 "MadeUpMember",
346 )
347 .unwrap()
348 .sender(":0.0")
349 .unwrap()
350 .build(&())
351 .unwrap();
352 let event = <$type>::try_from(&fake_msg);
353 event.expect("This should panic! Invalid event.");
354 }
355 #[cfg(feature = "zbus")]
356 #[test]
357 #[should_panic(expected = "should panic")]
358 fn zbus_msg_conversion_failure_correct_interface_and_member() -> () {
359 let fake_msg = zbus::MessageBuilder::signal(
360 "/org/a11y/sixtynine/fourtwenty",
361 <$type as GenericEvent>::DBUS_INTERFACE,
362 <$type as GenericEvent>::DBUS_MEMBER,
363 )
364 .unwrap()
365 .sender(":0.0")
366 .unwrap()
367 .build(&())
368 .unwrap();
369 let event = <$type>::try_from(&fake_msg);
370 event.expect("This should panic! Invalid event.");
371 }
372 #[cfg(feature = "zbus")]
373 #[test]
374 #[should_panic(expected = "should panic")]
375 fn zbus_msg_conversion_failure_correct_body() -> () {
376 let fake_msg = zbus::MessageBuilder::signal(
377 "/org/a11y/sixtynine/fourtwenty",
378 "org.a11y.atspi.accessible.technically.valid",
379 "FakeMember",
380 )
381 .unwrap()
382 .sender(":0.0")
383 .unwrap()
384 .build(&<$type>::default().body())
385 .unwrap();
386 let event = <$type>::try_from(&fake_msg);
387 event.expect("This should panic! Invalid event.");
388 }
389 #[cfg(feature = "zbus")]
390 #[test]
391 #[should_panic(expected = "should panic")]
392 fn zbus_msg_conversion_failure_correct_body_and_member() -> () {
393 let fake_msg = zbus::MessageBuilder::signal(
394 "/org/a11y/sixtynine/fourtwenty",
395 "org.a11y.atspi.accessible.technically.valid",
396 <$type as GenericEvent>::DBUS_MEMBER,
397 )
398 .unwrap()
399 .sender(":0.0")
400 .unwrap()
401 .build(&<$type>::default().body())
402 .unwrap();
403 let event = <$type>::try_from(&fake_msg);
404 event.expect("This should panic! Invalid event.");
405 }
406 };
407}
408
409macro_rules! event_wrapper_test_cases {
410 ($type:ty, $any_subtype:ty) => {
411 #[cfg(test)]
412 #[rename_item::rename(name($type), prefix = "events_tests_", case = "snake")]
413 mod foo {
414 use super::{$any_subtype, $type, Event, GenericEvent};
415 #[test]
416 fn into_and_try_from_event() {
417 let sub_type = <$any_subtype>::default();
418 let mod_type = <$type>::from(sub_type);
419 let event = Event::from(mod_type.clone());
420 let mod_type2 = <$type>::try_from(event.clone())
421 .expect("Could not create event type from event");
422 assert_eq!(
423 mod_type, mod_type2,
424 "Events were able to be parsed and encapsulated, but they have changed value"
425 );
426 }
427 #[cfg(feature = "zbus")]
428 #[test]
429 #[should_panic(expected = "should panic")]
430 fn zbus_msg_invalid_interface() {
431 let fake_msg = zbus::MessageBuilder::signal(
432 "/org/a11y/sixtynine/fourtwenty",
433 "org.a11y.atspi.technically.valid.lol",
434 <$any_subtype as GenericEvent>::DBUS_MEMBER,
435 )
436 .unwrap()
437 .sender(":0.0")
438 .unwrap()
439 .build(&<$any_subtype>::default().body())
440 .unwrap();
441 let mod_type = <$type>::try_from(&fake_msg);
442 mod_type.expect(
443 "This should panic! Could not convert message into a event wrapper type",
444 );
445 }
446 #[cfg(feature = "zbus")]
447 #[test]
448 #[should_panic(expected = "should panic")]
449 fn zbus_msg_invalid_member() {
450 let fake_msg = zbus::MessageBuilder::signal(
451 "/org/a11y/sixtynine/fourtwenty",
452 <$any_subtype as GenericEvent>::DBUS_INTERFACE,
453 "FakeFunctionLol",
454 )
455 .unwrap()
456 .sender(":0.0")
457 .unwrap()
458 .build(&<$any_subtype>::default().body())
459 .unwrap();
460 let mod_type = <$type>::try_from(&fake_msg);
461 mod_type.expect(
462 "This should panic! Could not convert message into a event wrapper type",
463 );
464 }
465 #[cfg(feature = "zbus")]
466 #[test]
467 #[should_panic(expected = "should panic")]
468 fn zbus_msg_invalid_member_and_interface() {
469 let fake_msg = zbus::MessageBuilder::signal(
470 "/org/a11y/sixtynine/fourtwenty",
471 "org.a11y.atspi.technically.allowed",
472 "FakeFunctionLol",
473 )
474 .unwrap()
475 .sender(":0.0")
476 .unwrap()
477 .build(&<$any_subtype>::default().body())
478 .unwrap();
479 let mod_type = <$type>::try_from(&fake_msg);
480 mod_type.expect(
481 "This should panic! Could not convert message into a event wrapper type",
482 );
483 }
484 #[cfg(feature = "zbus")]
485 #[test]
486 fn zbus_msg_conversion() {
487 let valid_msg = zbus::MessageBuilder::signal(
488 "/org/a11y/sixtynine/fourtwenty",
489 <$any_subtype as GenericEvent>::DBUS_INTERFACE,
490 <$any_subtype as GenericEvent>::DBUS_MEMBER,
491 )
492 .unwrap()
493 .sender(":0.0")
494 .unwrap()
495 .build(&<$any_subtype>::default().body())
496 .unwrap();
497 let mod_type = <$type>::try_from(&valid_msg);
498 mod_type.expect("Could not convert message into a event wrapper type");
499 }
500 }
501 };
502}
503
504macro_rules! event_test_cases {
505 ($type:ty) => {
506 #[cfg(test)]
507 #[rename_item::rename(name($type), prefix = "event_tests_", case = "snake")]
508 mod foo {
509 use super::{$type, Event, GenericEvent};
510
511 generic_event_test_case!($type);
512 event_enum_test_case!($type);
513 zbus_message_test_case!($type);
514 }
515 assert_impl_all!(
516 $type: Clone,
517 std::fmt::Debug,
518 serde::Serialize,
519 serde::Deserialize<'static>,
520 Default,
521 PartialEq,
522 Eq,
523 std::hash::Hash,
524 );
525 #[cfg(feature = "zbus")]
526 assert_impl_all!(zbus::Message: TryFrom<$type>);
527 };
528}
529
530#[macro_export]
533macro_rules! assert_eq_signatures {
534 ($lhs_sig:expr, $rhs_sig:expr) => {
535 assert!(
536 signatures_are_eq($lhs_sig, $rhs_sig),
537 "Signatures are not equal (Lhs: {}, Rhs: {})",
538 $lhs_sig,
539 $rhs_sig
540 );
541 };
542}