1#![allow(unused_macros)]
2#![allow(dead_code)]
3#![allow(unused_imports)]
4
5use std::{fs, path::PathBuf, str::FromStr};
6
7use crate::Result;
8
9/// Resolve XML path from either:
10///
11/// - provided argument,
12/// - default location (`xml/`, `XML/`, `../xml` or `../XML`) or
13/// - env_variable (`LOCKSTEP_XML_PATH`)
14///
15/// If no XML path is provided, it tries to find the default XML path.
16/// If the environment variable is set, it overrides the default, or
17/// argument path.
18///
19/// # Example
20///
21/// ```rust
22/// # use zbus_lockstep::resolve_xml_path;
23/// # use std::path::PathBuf;
24/// # fn main() {
25/// // path to XML files
26/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
27///
28/// let xml_path = resolve_xml_path(None).unwrap();
29/// assert_eq!(xml_path, PathBuf::from("../xml").canonicalize().unwrap());
30/// # }
31/// ```
32/// # Panics
33///
34/// Panics if no XML path is provided and the default XML path is not found.
35pub fn resolve_xml_path(xml: Option<&str>) -> Result<PathBuf> {
36 let mut xml = xml;
37 let current_dir: PathBuf = std::env::current_dir()?;
38
39 // We want to know the name of the crate we are expanded in.
40 let crate_name = std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| String::from("unknown"));
41
42 let current_dir_lower_case = current_dir.join("xml");
43 let current_dir_upper_case = current_dir.join("XML");
44
45 let parent_dir_lower_case = current_dir.join("../xml");
46 let parent_dir_upper_case = current_dir.join("../XML");
47
48 let crate_dir_lower_case = current_dir.join(&crate_name).join("xml");
49 let crate_dir_upper_case = current_dir.join(&crate_name).join("XML");
50
51 // If no XML path is provided, try to find the default XML path.
52 if xml.is_none() {
53 if current_dir_lower_case.exists() {
54 xml = Some(
55 current_dir_lower_case
56 .to_str()
57 .expect("current_dir_lower_case is valid UTF-8"),
58 );
59 }
60
61 if current_dir_upper_case.exists() {
62 xml = Some(
63 current_dir_upper_case
64 .to_str()
65 .expect("current_dir_upper_case is valid UTF-8"),
66 );
67 }
68
69 if parent_dir_lower_case.exists() {
70 xml = Some(
71 parent_dir_lower_case
72 .to_str()
73 .expect("parent_dir_lower_case is valid UTF-8"),
74 );
75 }
76
77 if parent_dir_upper_case.exists() {
78 xml = Some(
79 parent_dir_upper_case
80 .to_str()
81 .expect("parent_dir_upper_case is valid UTF-8"),
82 );
83 }
84
85 if crate_dir_lower_case.exists() {
86 xml = Some(
87 crate_dir_lower_case
88 .to_str()
89 .expect("crate_dir_lower_case is valid UTF-8"),
90 );
91 }
92
93 if crate_dir_upper_case.exists() {
94 xml = Some(
95 crate_dir_upper_case
96 .to_str()
97 .expect("crate_dir_upper_case is valid UTF-8"),
98 );
99 }
100 }
101
102 let env_xml_path = std::env::var("LOCKSTEP_XML_PATH");
103 if env_xml_path.is_ok() {
104 // Override the default, or argument path if the environment variable is set.
105 xml = env_xml_path.as_ref().map(|s| s.as_str()).ok();
106 }
107
108 // If no XML path is provided and the default XML path is not found, panic.
109 if xml.is_none() {
110 panic!(
111 "No XML path provided and default XML path not found. Current dir: \"{}\" ",
112 current_dir.to_str().expect("current_dir is valid UTF-8")
113 );
114 }
115
116 // Convert, canonicalize and return the XML path.
117 let xml = PathBuf::from_str(xml.unwrap())?;
118 Ok(xml.canonicalize()?)
119}
120
121/// A generic helper to find the file path and interface name of a member.
122#[doc(hidden)]
123#[macro_export]
124macro_rules! find_definition_in_dbus_xml {
125 ($xml_path_buf:expr, $member:expr, $iface:expr, $msg_type:expr) => {{
126 use $crate::MsgType;
127
128 let xml_path_buf: std::path::PathBuf = $xml_path_buf;
129 let member: &str = $member;
130 let iface: Option<String> = $iface;
131 let msg_type: MsgType = $msg_type;
132
133 let mut xml_file_path = None;
134 let mut interface_name = None;
135
136 let read_dir = std::fs::read_dir(&xml_path_buf).expect("Failed to read XML directory");
137
138 // Walk the XML files in the directory.
139 for entry in read_dir {
140 let entry = entry.expect("Failed to read entry");
141
142 // Skip directories and non-XML files.
143 if entry.path().is_dir() || entry.path().extension().unwrap() != "xml" {
144 continue;
145 }
146
147 let entry_path = entry.path().clone();
148 let file = std::fs::File::open(entry.path()).expect("Failed to open file");
149 let node = $crate::zbus_xml::Node::from_reader(file).expect("Failed to parse XML file");
150
151 for interface in node.interfaces() {
152 // If called with an `iface` arg, skip he interfaces that do not match.
153 if iface.is_some() && interface.name().as_str() != iface.clone().unwrap() {
154 continue;
155 }
156
157 match msg_type {
158 MsgType::Method => {
159 for dbus_item in interface.methods() {
160 if dbus_item.name() == member {
161 if interface_name.is_some() {
162 panic!(
163 "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.",
164 msg_type, member
165 );
166 }
167 interface_name = Some(interface.name().to_string());
168 xml_file_path = Some(entry_path.clone());
169 continue;
170 }
171 }
172 }
173 MsgType::Signal => {
174 for dbus_item in interface.signals() {
175 if dbus_item.name() == member {
176 if interface_name.is_some() {
177 panic!(
178 "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.",
179 msg_type, member
180 );
181 }
182 interface_name = Some(interface.name().to_string());
183 xml_file_path = Some(entry_path.clone());
184 continue;
185 }
186 }
187 }
188 MsgType::Property => {
189 for dbus_item in interface.properties() {
190 if dbus_item.name() == member {
191 if interface_name.is_some() {
192 panic!(
193 "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.",
194 msg_type, member
195 );
196 }
197 interface_name = Some(interface.name().to_string());
198 xml_file_path = Some(entry_path.clone());
199 continue;
200 }
201 }
202 }
203 };
204 }
205 }
206
207 // If the interface member was not found, return an error.
208 if xml_file_path.is_none() {
209 panic!("Member not found in XML files.");
210 }
211
212 (xml_file_path.unwrap(), interface_name.unwrap())
213 }};
214}
215
216/// Retrieve the signature of a method's return type.
217///
218/// This macro will take a method member name and return the signature of the
219/// return type.
220///
221/// Essentially a wrapper around [`zbus_lockstep::get_method_return_type`],
222/// but this macro tries to do its job with less arguments.
223///
224/// It will search in the XML specification of the method for the return type
225/// and return the signature of that type.
226///
227/// If multiple interfaces offer the same method, you will need to specify the
228/// interface name as well.
229///
230/// This macro can be called with or without the interface name.
231///
232/// # Examples
233///
234/// Basic usage:
235///
236/// ```rust
237/// use zbus_lockstep::method_return_signature;
238/// use zvariant::Signature;
239///
240/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
241///
242/// let sig = method_return_signature!("RequestName");
243/// assert_eq!(&sig, &Signature::from_str_unchecked("u"));
244/// ```
245/// The macro supports colling arguments with identifiers as well as without.
246/// The macro may also be called with an interface name or interface and argument name:
247///
248/// ```rust
249/// # use zbus_lockstep::{method_return_signature};
250/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
251/// let _sig = method_return_signature!("RequestName", "org.example.Node", "grape");
252///
253/// // or alternatively
254///
255/// let _sig = method_return_signature!(member: "RequestName", interface: "org.example.Node", argument: "grape");
256/// ```
257#[macro_export]
258macro_rules! method_return_signature {
259 ($member:expr) => {{
260 use $crate::MsgType;
261 let member = $member;
262
263 // Looking for default path or path specified by environment variable.
264 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
265 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
266 "Failed to resolve XML path, current dir: {}",
267 current_dir.to_str().unwrap()
268 ));
269
270 // Find the definition of the method in the XML specification.
271 let (file_path, interface_name) =
272 $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method);
273
274 let file = std::fs::File::open(file_path).expect("Failed to open file");
275 $crate::get_method_return_type(file, &interface_name, member, None)
276 .expect("Failed to get method arguments type signature")
277 }};
278
279 (member: $member:expr) => {
280 $crate::method_return_signature!($member)
281 };
282
283 ($member:expr, $interface:expr) => {{
284 let member = $member;
285 use $crate::MsgType;
286
287 let interface = Some($interface.to_string());
288
289 // Looking for default path or path specified by environment variable.
290 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
291 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
292 "Failed to resolve XML path, current dir: {}",
293 current_dir.to_str().unwrap()
294 ));
295
296 // Find the definition of the method in the XML specification.
297 let (file_path, interface_name) =
298 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
299
300 let file = std::fs::File::open(file_path).expect("Failed to open file");
301 $crate::get_method_return_type(file, &interface_name, member, None)
302 .expect("Failed to get method arguments type signature")
303 }};
304
305 (member: $member:expr, interface: $interface:expr) => {
306 $crate::method_return_signature!($member, $interface)
307 };
308
309 ($member:expr, $interface:expr, $argument:expr) => {{
310 let member = $member;
311 use $crate::MsgType;
312
313 let interface = Some($interface.to_string());
314 let argument = Some($argument);
315
316 // Looking for default path or path specified by environment variable.
317 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
318 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
319 "Failed to resolve XML path, current dir: {}",
320 current_dir.to_str().unwrap()
321 ));
322
323 // Find the definition of the method in the XML specification.
324 let (file_path, interface_name) =
325 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
326
327 let file = std::fs::File::open(file_path).expect("Failed to open file");
328 $crate::get_method_return_type(file, &interface_name, member, argument)
329 .expect("Failed to get method argument(s) type signature")
330 }};
331
332 (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
333 $crate::method_return_signature!($member, $interface, $argument)
334 };
335}
336
337/// Retrieve the signature of a method's arguments.
338///
339/// Essentially a wrapper around [`zbus_lockstep::get_method_args_type`],
340/// but this macro tries to do its job with less arguments.
341///
342/// This macro will take a method member name and return the signature of the
343/// arguments type.
344///
345/// It will search in the XML specification of the method for the arguments type
346/// and return the signature of that type.
347///
348/// If multiple interfaces offer the same member, you will need to
349/// specify the interface name as well.
350///
351/// This macro can be called with or without the interface name.
352///
353/// # Examples
354///
355/// ```rust
356/// use zbus_lockstep::method_args_signature;
357/// use zvariant::Signature;
358///
359/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
360///
361/// let sig = method_args_signature!("RequestName");
362/// assert_eq!(&sig, &Signature::from_str_unchecked("(su)"));
363/// ```
364/// The macro supports colling arguments with identifiers as well as without.
365/// The macro may also be called with an interface name or interface and argument name:
366///
367/// ```rust
368/// # use zbus_lockstep::{method_args_signature};
369/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
370/// let _sig = method_args_signature!("RequestName", "org.example.Node", "apple");
371///
372/// // or alternatively
373///
374/// let _sig = method_args_signature!(member: "RequestName", interface: "org.example.Node", argument: "apple");
375/// ```
376#[macro_export]
377macro_rules! method_args_signature {
378 ($member:expr) => {{
379 use $crate::MsgType;
380 let member = $member;
381
382 // Looking for default path or path specified by environment variable.
383 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
384 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
385 "Failed to resolve XML path, current dir: {}",
386 current_dir.to_str().unwrap()
387 ));
388
389 // Find the definition of the method in the XML specification.
390 let (file_path, interface_name) =
391 $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method);
392
393 let file = std::fs::File::open(file_path).expect("Failed to open file");
394 $crate::get_method_args_type(file, &interface_name, member, None)
395 .expect("Failed to get method arguments type signature")
396 }};
397
398 (member: $member:expr) => {
399 $crate::method_args_signature!($member)
400 };
401
402 ($member:expr, $interface:expr) => {{
403 use $crate::MsgType;
404 let member = $member;
405
406 let interface = Some($interface.to_string());
407
408 // Looking for default path or path specified by environment variable.
409 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
410 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
411 "Failed to resolve XML path, current dir: {}",
412 current_dir.to_str().unwrap()
413 ));
414
415 // Find the definition of the method in the XML specification.
416 let (file_path, interface_name) =
417 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
418
419 let file = std::fs::File::open(file_path).expect("Failed to open file");
420 $crate::get_method_args_type(file, &interface_name, member, None)
421 .expect("Failed to get method arguments type signature")
422 }};
423
424 (member: $member:expr, interface: $interface:expr) => {
425 $crate::method_args_signature!($member, $interface)
426 };
427
428 ($member:expr, $interface:expr, $argument:expr) => {{
429 use $crate::MsgType;
430 let member = $member;
431 let interface = Some($interface.to_string());
432
433 let argument = Some($argument);
434
435 // Looking for default path or path specified by environment variable.
436 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
437
438 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
439 "Failed to resolve XML path, current dir: {}",
440 current_dir.to_str().unwrap()
441 ));
442 // Find the definition of the method in the XML specification.
443 let (file_path, interface_name) =
444 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
445
446 let file = std::fs::File::open(file_path).expect("Failed to open file");
447 $crate::get_method_args_type(file, &interface_name, member, argument)
448 .expect("Failed to get method argument(s) type signature")
449 }};
450
451 (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
452 $crate::method_args_signature!($member, $interface, $argument)
453 };
454}
455
456/// Retrieve the signature of a signal's body type.
457///
458/// Essentially a wrapper around [`zbus_lockstep::get_signal_body_type`],
459/// but this macro tries to find it with less arguments.
460///
461/// This macro will take a signal member name and return the signature of the
462/// signal body type.
463///
464/// If multiple interfaces offer the same member, you will need to
465/// specify the interface name as well.
466///
467/// This macro can be called with or without the interface name.
468///
469/// # Examples
470///
471/// ```rust
472/// use zbus_lockstep::signal_body_type_signature;
473/// use zvariant::Signature;
474///
475/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
476///
477/// let sig = signal_body_type_signature!("AddNode");
478/// assert_eq!(&sig, &Signature::from_str_unchecked("(so)"));
479/// ```
480/// The macro supports colling arguments with identifiers as well as without.
481/// The macro may also be called with an interface name or interface and argument name:
482///
483/// ```rust
484/// # use zbus_lockstep::{signal_body_type_signature};
485/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
486/// let _sig = signal_body_type_signature!("Alert", "org.example.Node", "color");
487///
488/// // or alternatively
489///
490/// let _sig = signal_body_type_signature!(member: "Alert", interface: "org.example.Node", argument: "color");
491/// ```
492#[macro_export]
493macro_rules! signal_body_type_signature {
494 ($member:expr) => {{
495 use $crate::MsgType;
496 let member = $member;
497
498 // Looking for default path or path specified by environment variable.
499 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
500 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
501 "Failed to resolve XML path, current dir: {}",
502 current_dir.to_str().unwrap()
503 ));
504
505 // Find the definition of the method in the XML specification.
506 let (file_path, interface_name) =
507 $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Signal);
508
509 let file = std::fs::File::open(file_path).expect("Failed to open file");
510
511 $crate::get_signal_body_type(file, &interface_name, member, None)
512 .expect("Failed to get method arguments type signature")
513 }};
514
515 (member: $member:expr) => {
516 $crate::signal_body_type_signature!($member)
517 };
518
519 ($member:expr, $interface:expr) => {{
520 use $crate::MsgType;
521 let member = $member;
522 let interface = Some($interface.to_string());
523
524 // Looking for default path or path specified by environment variable.
525 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
526 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
527 "Failed to resolve XML path, current dir: {}",
528 current_dir.to_str().unwrap()
529 ));
530
531 // Find the definition of the method in the XML specification.
532 let (file_path, interface_name) =
533 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal);
534
535 let file = std::fs::File::open(file_path).expect("Failed to open file");
536 $crate::get_signal_body_type(file, &interface_name, member, None)
537 .expect("Failed to get method arguments type signature")
538 }};
539
540 (member: $member:expr, interface: $interface:expr) => {
541 $crate::signal_body_type_signature!($member, $interface)
542 };
543
544 ($member:expr, $interface:expr, $argument:expr) => {{
545 use $crate::MsgType;
546 let member = $member;
547 let interface = Some($interface.to_string());
548
549 let argument = Some($argument);
550
551 // Looking for default path or path specified by environment variable.
552 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
553
554 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
555 "Failed to resolve XML path, current dir: {}",
556 current_dir.to_str().unwrap()
557 ));
558
559 // Find the definition of the method in the XML specification.
560 let (file_path, interface_name) =
561 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal);
562
563 let file = std::fs::File::open(file_path).expect("Failed to open file");
564 $crate::get_signal_body_type(file, &interface_name, member, argument)
565 .expect("Failed to get method argument(s) type signature")
566 }};
567
568 (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
569 $crate::signal_body_type_signature!($member, $interface, $argument)
570 };
571}
572
573/// Retrieve the signature of a property's type.
574///
575/// Essentially a wrapper around [`zbus_lockstep::get_property_type`],
576/// but this macro tries to do with less arguments.
577///
578/// This macro will take a property name and return the signature of the
579/// property's type.
580///
581/// If multiple interfaces offer the same member, you will need to
582/// specify the interface name as well.
583///
584/// This macro can be called with or without the interface name.
585///
586/// # Examples
587///
588/// ```rust
589/// use zbus_lockstep::property_type_signature;
590/// use zvariant::Signature;
591///
592/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
593///
594/// let sig = property_type_signature!("Features");
595/// assert_eq!(&sig, &Signature::from_str_unchecked("as"));
596/// ```
597/// The member name and/or interface name can be used tp identify the arguments:
598///
599/// ```rust
600/// # use zbus_lockstep::{property_type_signature};
601/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
602/// let _sig = property_type_signature!(member: "Features", interface: "org.example.Node");
603/// ```
604#[macro_export]
605macro_rules! property_type_signature {
606 ($member:expr) => {{
607 use $crate::MsgType;
608 let member = $member;
609
610 // Looking for default path or path specified by environment variable.
611 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
612 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
613 "Failed to resolve XML path, current dir: {}",
614 current_dir.to_str().unwrap()
615 ));
616
617 // Find the definition of the method in the XML specification.
618 let (file_path, interface_name) =
619 $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Property);
620
621 let file = std::fs::File::open(file_path).expect("Failed to open file");
622
623 $crate::get_property_type(file, &interface_name, member)
624 .expect("Failed to get property type signature")
625 }};
626
627 (member: $member:expr) => {
628 $crate::property_type_signature!($member)
629 };
630
631 ($member:expr, $interface:expr) => {{
632 use $crate::MsgType;
633 let member = $member;
634 let interface = Some($interface.to_string());
635
636 // Looking for default path or path specified by environment variable.
637 let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
638 let xml_path = $crate::resolve_xml_path(None).expect(&format!(
639 "Failed to resolve XML path, current dir: {}",
640 current_dir.to_str().unwrap()
641 ));
642
643 // Find the definition of the method in the XML specification.
644 let (file_path, interface_name) =
645 $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Property);
646
647 let file = std::fs::File::open(file_path).expect("Failed to open file");
648 $crate::get_property_type(file, &interface_name, member)
649 .expect("Failed to get property type signature")
650 }};
651
652 (member: $member:expr, interface: $interface:expr) => {
653 $crate::property_type_signature!($member, $interface)
654 };
655}
656
657#[cfg(test)]
658mod test {
659 use zvariant::Signature;
660
661 use crate::signal_body_type_signature;
662
663 #[test]
664 fn test_signal_body_signature_macro() {
665 // path to XML files can be set by environment variable
666 // std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
667 // But `resolve_xml_path` can find the `xml` in parent by itself.
668
669 let sig = crate::signal_body_type_signature!("AddNode");
670 assert_eq!(&sig, &zvariant::Signature::from_str_unchecked("(so)"));
671 }
672
673 #[test]
674 fn test_signal_body_signature_macro_with_identifier() {
675 let sig = crate::signal_body_type_signature!(member: "AddNode");
676 assert_eq!(sig, Signature::from_str_unchecked("(so)"));
677 }
678
679 #[test]
680 fn test_signal_body_signature_macro_with_interface() {
681 let sig = crate::signal_body_type_signature!("AddNode", "org.example.Node");
682 assert_eq!(sig, Signature::from_str_unchecked("(so)"));
683 }
684
685 #[test]
686 fn test_signal_body_signature_macro_with_interface_and_identifiers() {
687 let sig =
688 crate::signal_body_type_signature!(member: "AddNode", interface: "org.example.Node");
689 assert_eq!(sig, Signature::from_str_unchecked("(so)"));
690 }
691
692 #[test]
693 fn test_signal_body_signature_macro_with_argument_and_interface() {
694 let sig = crate::signal_body_type_signature!("Alert", "org.example.Node", "volume");
695 assert_eq!(sig, Signature::from_str_unchecked("d"));
696 }
697
698 #[test]
699 fn test_signal_body_signature_macro_with_argument_and_identifiers_and_interface() {
700 let sig = crate::signal_body_type_signature!(
701 member: "Alert",
702 interface: "org.example.Node",
703 argument: "urgent"
704 );
705 assert_eq!(sig, Signature::from_str_unchecked("b"));
706 }
707
708 #[test]
709 fn test_method_args_signature_macro() {
710 let sig = crate::method_args_signature!("RequestName");
711 assert_eq!(sig, Signature::from_str_unchecked("(su)"));
712 }
713
714 #[test]
715 fn test_method_args_signature_macro_with_identifier() {
716 let sig = crate::method_args_signature!(member: "RequestName");
717 assert_eq!(sig, Signature::from_str_unchecked("(su)"));
718 }
719
720 #[test]
721 fn test_method_args_signature_macro_with_interface() {
722 let sig = crate::method_args_signature!("RequestName", "org.example.Node");
723 assert_eq!(sig, Signature::from_str_unchecked("(su)"));
724 }
725
726 #[test]
727 fn test_method_args_signature_macro_with_interface_and_identifiers() {
728 let sig =
729 crate::method_args_signature!(member: "RequestName", interface: "org.example.Node");
730 assert_eq!(sig, Signature::from_str_unchecked("(su)"));
731 }
732
733 #[test]
734 fn test_method_args_signature_macro_with_argument_and_interface() {
735 let sig = crate::method_args_signature!("RequestName", "org.example.Node", "apple");
736 assert_eq!(sig, Signature::from_str_unchecked("s"));
737 }
738
739 #[test]
740 fn test_method_args_signature_macro_with_argument_and_identifiers_and_interface() {
741 let sig = crate::method_args_signature!(
742 member: "RequestName",
743 interface: "org.example.Node",
744 argument: "orange"
745 );
746 assert_eq!(sig, Signature::from_str_unchecked("u"));
747 }
748
749 #[test]
750 fn test_method_return_signature_macro() {
751 let sig = crate::method_return_signature!("RequestName");
752 assert_eq!(sig, Signature::from_str_unchecked("u"));
753 }
754
755 #[test]
756 fn test_method_return_signature_macro_with_identifier() {
757 let sig = crate::method_return_signature!(member: "RequestName");
758 assert_eq!(sig, Signature::from_str_unchecked("u"));
759 }
760
761 #[test]
762 fn test_method_return_signature_macro_with_interface() {
763 let sig = crate::method_return_signature!("RequestName", "org.example.Node");
764 assert_eq!(sig, Signature::from_str_unchecked("u"));
765 }
766
767 #[test]
768 fn test_method_return_signature_macro_with_interface_and_identifiers() {
769 let sig =
770 crate::method_return_signature!(member: "RequestName", interface: "org.example.Node");
771 assert_eq!(sig, Signature::from_str_unchecked("u"));
772 }
773
774 #[test]
775 fn test_method_return_signature_macro_with_argument_and_interface() {
776 let sig = crate::method_return_signature!("RequestName", "org.example.Node", "grape");
777 assert_eq!(sig, Signature::from_str_unchecked("u"));
778 }
779
780 #[test]
781 fn test_method_return_signature_macro_with_argument_and_identifiers_and_interface() {
782 let sig = crate::method_return_signature!(
783 member: "RequestName",
784 interface: "org.example.Node",
785 argument: "grape"
786 );
787 assert_eq!(sig, Signature::from_str_unchecked("u"));
788 }
789
790 #[test]
791 fn test_property_type_signature_macro() {
792 let sig = crate::property_type_signature!("Features");
793 assert_eq!(sig, Signature::from_str_unchecked("as"));
794 }
795
796 #[test]
797 fn test_property_type_signature_macro_with_identifier() {
798 let sig = crate::property_type_signature!(member: "Features");
799 assert_eq!(sig, Signature::from_str_unchecked("as"));
800 }
801
802 #[test]
803 fn test_property_type_signature_macro_with_interface() {
804 let sig = crate::property_type_signature!("Features", "org.example.Node");
805 assert_eq!(sig, Signature::from_str_unchecked("as"));
806 }
807
808 #[test]
809 fn test_property_type_signature_macro_with_interface_and_identifiers() {
810 let sig =
811 crate::property_type_signature!(member: "Features", interface: "org.example.Node");
812 assert_eq!(sig, Signature::from_str_unchecked("as"));
813 }
814}
815