zbus_lockstep/
macros.rs

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