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                            continue;
173                        }
174                    }
175                }
176                MsgType::Signal => {
177                    for dbus_item in interface.signals() {
178                        if dbus_item.name() == member {
179                            if interface_name.is_some() {
180                                panic!(
181                                    "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.",
182                                    msg_type, member
183                                );
184                            }
185                            interface_name = Some(interface.name().to_string());
186                            xml_file_path = Some(entry_path.clone());
187                            continue;
188                        }
189                    }
190                }
191                MsgType::Property => {
192                    for dbus_item in interface.properties() {
193                        if dbus_item.name() == member {
194                            if interface_name.is_some() {
195                                panic!(
196                                    "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.",
197                                    msg_type, member
198                                );
199                            }
200                            interface_name = Some(interface.name().to_string());
201                            xml_file_path = Some(entry_path.clone());
202                            continue;
203                        }
204                    }
205                }
206            };
207        }
208    }
209
210    // If the interface member was not found, return an error.
211    if xml_file_path.is_none() {
212        panic!("Member not found in XML files.");
213    }
214
215    (xml_file_path.unwrap(), interface_name.unwrap())
216    }};
217}
218
219/// Retrieve the signature of a method's return type.
220///
221/// This macro will take a method member name and return the signature of the
222/// return type.
223///
224/// Essentially a wrapper around [`zbus_lockstep::get_method_return_type`],
225/// but this macro tries to do its job with less arguments.
226///
227/// It will search in the XML specification of the method for the return type
228/// and return the signature of that type.
229///
230/// If multiple interfaces offer the same method, you will need to specify the
231/// interface name as well.
232///
233/// This macro can be called with or without the interface name.
234///
235/// # Examples
236///
237/// Basic usage:
238///
239/// ```rust
240/// use std::str::FromStr;
241/// use zbus_lockstep::method_return_signature;
242/// use zvariant::Signature;
243///
244/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
245///
246/// let sig = method_return_signature!("RequestName");
247/// assert_eq!(&sig, &Signature::from_str("u").expect("Valid signature pattern"));
248/// ```
249/// The macro supports colling arguments with identifiers as well as without.
250/// The macro may also be called with an interface name or interface and argument name:
251///
252/// ```rust
253/// # use zbus_lockstep::{method_return_signature};
254/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
255/// let _sig = method_return_signature!("RequestName", "org.example.Node", "grape");
256///
257/// // or alternatively
258///
259/// let _sig = method_return_signature!(member: "RequestName", interface: "org.example.Node", argument: "grape");
260/// ```
261#[macro_export]
262macro_rules! method_return_signature {
263    ($member:expr) => {{
264        use $crate::MsgType;
265        let member = $member;
266
267        // Looking for default path or path specified by environment variable.
268        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
269        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
270            "Failed to resolve XML path, current dir: {}",
271            current_dir.to_str().unwrap()
272        ));
273
274        // Find the definition of the method in the XML specification.
275        let (file_path, interface_name) =
276            $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method);
277
278        let file = std::fs::File::open(file_path).expect("Failed to open file");
279        $crate::get_method_return_type(file, &interface_name, member, None)
280            .expect("Failed to get method arguments type signature")
281    }};
282
283    (member: $member:expr) => {
284        $crate::method_return_signature!($member)
285    };
286
287    ($member:expr, $interface:expr) => {{
288        let member = $member;
289        use $crate::MsgType;
290
291        let interface = Some($interface.to_string());
292
293        // Looking for default path or path specified by environment variable.
294        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
295        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
296            "Failed to resolve XML path, current dir: {}",
297            current_dir.to_str().unwrap()
298        ));
299
300        // Find the definition of the method in the XML specification.
301        let (file_path, interface_name) =
302            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
303
304        let file = std::fs::File::open(file_path).expect("Failed to open file");
305        $crate::get_method_return_type(file, &interface_name, member, None)
306            .expect("Failed to get method arguments type signature")
307    }};
308
309    (member: $member:expr, interface: $interface:expr) => {
310        $crate::method_return_signature!($member, $interface)
311    };
312
313    ($member:expr, $interface:expr, $argument:expr) => {{
314        let member = $member;
315        use $crate::MsgType;
316
317        let interface = Some($interface.to_string());
318        let argument = Some($argument);
319
320        // Looking for default path or path specified by environment variable.
321        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
322        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
323            "Failed to resolve XML path, current dir: {}",
324            current_dir.to_str().unwrap()
325        ));
326
327        // Find the definition of the method in the XML specification.
328        let (file_path, interface_name) =
329            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
330
331        let file = std::fs::File::open(file_path).expect("Failed to open file");
332        $crate::get_method_return_type(file, &interface_name, member, argument)
333            .expect("Failed to get method argument(s) type signature")
334    }};
335
336    (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
337        $crate::method_return_signature!($member, $interface, $argument)
338    };
339}
340
341/// Retrieve the signature of a method's arguments.
342///
343/// Essentially a wrapper around [`zbus_lockstep::get_method_args_type`],
344/// but this macro tries to do its job with less arguments.
345///
346/// This macro will take a method member name and return the signature of the
347/// arguments type.
348///
349/// It will search in the XML specification of the method for the arguments type
350/// and return the signature of that type.
351///
352/// If multiple interfaces offer the same member, you will need to
353/// specify the interface name as well.
354///
355/// This macro can be called with or without the interface name.
356///
357/// # Examples
358///
359/// ```rust
360/// use std::str::FromStr;
361/// use zbus_lockstep::method_args_signature;
362/// use zvariant::Signature;
363///
364/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
365///
366/// let sig = method_args_signature!("RequestName");
367/// assert_eq!(&sig, &Signature::from_str("(su)").expect("Valid signature pattern"));
368/// ```
369/// The macro supports colling arguments with identifiers as well as without.
370/// The macro may also be called with an interface name or interface and argument name:
371///
372/// ```rust
373/// # use zbus_lockstep::{method_args_signature};
374/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
375/// let _sig = method_args_signature!("RequestName", "org.example.Node", "apple");
376///
377/// // or alternatively
378///
379/// let _sig = method_args_signature!(member: "RequestName", interface: "org.example.Node", argument: "apple");
380/// ```
381#[macro_export]
382macro_rules! method_args_signature {
383    ($member:expr) => {{
384        use $crate::MsgType;
385        let member = $member;
386
387        // Looking for default path or path specified by environment variable.
388        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
389        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
390            "Failed to resolve XML path, current dir: {}",
391            current_dir.to_str().unwrap()
392        ));
393
394        // Find the definition of the method in the XML specification.
395        let (file_path, interface_name) =
396            $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method);
397
398        let file = std::fs::File::open(file_path).expect("Failed to open file");
399        $crate::get_method_args_type(file, &interface_name, member, None)
400            .expect("Failed to get method arguments type signature")
401    }};
402
403    (member: $member:expr) => {
404        $crate::method_args_signature!($member)
405    };
406
407    ($member:expr, $interface:expr) => {{
408        use $crate::MsgType;
409        let member = $member;
410
411        let interface = Some($interface.to_string());
412
413        // Looking for default path or path specified by environment variable.
414        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
415        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
416            "Failed to resolve XML path, current dir: {}",
417            current_dir.to_str().unwrap()
418        ));
419
420        // Find the definition of the method in the XML specification.
421        let (file_path, interface_name) =
422            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
423
424        let file = std::fs::File::open(file_path).expect("Failed to open file");
425        $crate::get_method_args_type(file, &interface_name, member, None)
426            .expect("Failed to get method arguments type signature")
427    }};
428
429    (member: $member:expr, interface: $interface:expr) => {
430        $crate::method_args_signature!($member, $interface)
431    };
432
433    ($member:expr, $interface:expr, $argument:expr) => {{
434        use $crate::MsgType;
435        let member = $member;
436        let interface = Some($interface.to_string());
437
438        let argument = Some($argument);
439
440        // Looking for default path or path specified by environment variable.
441        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
442
443        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
444            "Failed to resolve XML path, current dir: {}",
445            current_dir.to_str().unwrap()
446        ));
447        // Find the definition of the method in the XML specification.
448        let (file_path, interface_name) =
449            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method);
450
451        let file = std::fs::File::open(file_path).expect("Failed to open file");
452        $crate::get_method_args_type(file, &interface_name, member, argument)
453            .expect("Failed to get method argument(s) type signature")
454    }};
455
456    (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
457        $crate::method_args_signature!($member, $interface, $argument)
458    };
459}
460
461/// Retrieve the signature of a signal's body type.
462///
463/// Essentially a wrapper around [`zbus_lockstep::get_signal_body_type`],
464/// but this macro tries to find it with less arguments.
465///
466/// This macro will take a signal member name and return the signature of the
467/// signal body type.
468///
469/// If multiple interfaces offer the same member, you will need to
470/// specify the interface name as well.
471///
472/// This macro can be called with or without the interface name.
473///
474/// # Examples
475///
476/// ```rust
477/// use std::str::FromStr;
478/// use zbus_lockstep::signal_body_type_signature;
479/// use zvariant::Signature;
480///
481/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
482///
483/// let sig = signal_body_type_signature!("AddNode");
484/// assert_eq!(&sig, &Signature::from_str("(so)").expect("Valid signature pattern"));
485/// ```
486/// The macro supports colling arguments with identifiers as well as without.
487/// The macro may also be called with an interface name or interface and argument name:
488///
489/// ```rust
490/// # use zbus_lockstep::{signal_body_type_signature};
491/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
492/// let _sig = signal_body_type_signature!("Alert", "org.example.Node", "color");
493///
494/// // or alternatively
495///
496/// let _sig = signal_body_type_signature!(member: "Alert", interface: "org.example.Node", argument: "color");
497/// ```
498#[macro_export]
499macro_rules! signal_body_type_signature {
500    ($member:expr) => {{
501        use $crate::MsgType;
502        let member = $member;
503
504        // Looking for default path or path specified by environment variable.
505        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
506        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
507            "Failed to resolve XML path, current dir: {}",
508            current_dir.to_str().unwrap()
509        ));
510
511        // Find the definition of the method in the XML specification.
512        let (file_path, interface_name) =
513            $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Signal);
514
515        let file = std::fs::File::open(file_path).expect("Failed to open file");
516
517        $crate::get_signal_body_type(file, &interface_name, member, None)
518            .expect("Failed to get method arguments type signature")
519    }};
520
521    (member: $member:expr) => {
522        $crate::signal_body_type_signature!($member)
523    };
524
525    ($member:expr, $interface:expr) => {{
526        use $crate::MsgType;
527        let member = $member;
528        let interface = Some($interface.to_string());
529
530        // Looking for default path or path specified by environment variable.
531        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
532        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
533            "Failed to resolve XML path, current dir: {}",
534            current_dir.to_str().unwrap()
535        ));
536
537        // Find the definition of the method in the XML specification.
538        let (file_path, interface_name) =
539            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal);
540
541        let file = std::fs::File::open(file_path).expect("Failed to open file");
542        $crate::get_signal_body_type(file, &interface_name, member, None)
543            .expect("Failed to get method arguments type signature")
544    }};
545
546    (member: $member:expr, interface: $interface:expr) => {
547        $crate::signal_body_type_signature!($member, $interface)
548    };
549
550    ($member:expr, $interface:expr, $argument:expr) => {{
551        use $crate::MsgType;
552        let member = $member;
553        let interface = Some($interface.to_string());
554
555        let argument = Some($argument);
556
557        // Looking for default path or path specified by environment variable.
558        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
559
560        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
561            "Failed to resolve XML path, current dir: {}",
562            current_dir.to_str().unwrap()
563        ));
564
565        // Find the definition of the method in the XML specification.
566        let (file_path, interface_name) =
567            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal);
568
569        let file = std::fs::File::open(file_path).expect("Failed to open file");
570        $crate::get_signal_body_type(file, &interface_name, member, argument)
571            .expect("Failed to get method argument(s) type signature")
572    }};
573
574    (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => {
575        $crate::signal_body_type_signature!($member, $interface, $argument)
576    };
577}
578
579/// Retrieve the signature of a property's type.
580///
581/// Essentially a wrapper around [`zbus_lockstep::get_property_type`],
582/// but this macro tries to do with less arguments.
583///
584/// This macro will take a property name and return the signature of the
585/// property's type.
586///
587/// If multiple interfaces offer the same member, you will need to
588/// specify the interface name as well.
589///
590/// This macro can be called with or without the interface name.
591///
592/// # Examples
593///
594/// ```rust
595/// use std::str::FromStr;
596/// use zbus_lockstep::property_type_signature;
597/// use zvariant::Signature;
598///
599/// std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
600///
601/// let sig = property_type_signature!("Features");
602/// assert_eq!(&sig, &Signature::from_str("as").expect("Valid signature pattern"));
603/// ```
604/// The member name and/or interface name can be used tp identify the arguments:
605///
606/// ```rust
607/// # use zbus_lockstep::{property_type_signature};
608/// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
609/// let _sig = property_type_signature!(member: "Features", interface: "org.example.Node");
610/// ```
611#[macro_export]
612macro_rules! property_type_signature {
613    ($member:expr) => {{
614        use $crate::MsgType;
615        let member = $member;
616
617        // Looking for default path or path specified by environment variable.
618        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
619        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
620            "Failed to resolve XML path, current dir: {}",
621            current_dir.to_str().unwrap()
622        ));
623
624        // Find the definition of the method in the XML specification.
625        let (file_path, interface_name) =
626            $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Property);
627
628        let file = std::fs::File::open(file_path).expect("Failed to open file");
629
630        $crate::get_property_type(file, &interface_name, member)
631            .expect("Failed to get property type signature")
632    }};
633
634    (member: $member:expr) => {
635        $crate::property_type_signature!($member)
636    };
637
638    ($member:expr, $interface:expr) => {{
639        use $crate::MsgType;
640        let member = $member;
641        let interface = Some($interface.to_string());
642
643        // Looking for default path or path specified by environment variable.
644        let current_dir: std::path::PathBuf = std::env::current_dir().unwrap();
645        let xml_path = $crate::resolve_xml_path(None).expect(&format!(
646            "Failed to resolve XML path, current dir: {}",
647            current_dir.to_str().unwrap()
648        ));
649
650        // Find the definition of the method in the XML specification.
651        let (file_path, interface_name) =
652            $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Property);
653
654        let file = std::fs::File::open(file_path).expect("Failed to open file");
655        $crate::get_property_type(file, &interface_name, member)
656            .expect("Failed to get property type signature")
657    }};
658
659    (member: $member:expr, interface: $interface:expr) => {
660        $crate::property_type_signature!($member, $interface)
661    };
662}
663
664#[cfg(test)]
665mod test {
666    use std::str::FromStr;
667
668    use zvariant::Signature;
669
670    use crate::signal_body_type_signature;
671
672    #[test]
673    fn test_signal_body_signature_macro() {
674        // path to XML files can be set by environment variable
675        // std::env::set_var("LOCKSTEP_XML_PATH", "../xml");
676        // But `resolve_xml_path` can find the `xml` in parent by itself.
677
678        let sig = crate::signal_body_type_signature!("AddNode");
679        assert_eq!(
680            &sig,
681            &zvariant::Signature::from_str("(so)").expect("Valid signature pattern")
682        );
683    }
684
685    #[test]
686    fn test_signal_body_signature_macro_with_identifier() {
687        let sig = crate::signal_body_type_signature!(member: "AddNode");
688        assert_eq!(
689            sig,
690            Signature::from_str("(so)").expect("Valid signature pattern")
691        );
692    }
693
694    #[test]
695    fn test_signal_body_signature_macro_with_interface() {
696        let sig = crate::signal_body_type_signature!("AddNode", "org.example.Node");
697        assert_eq!(
698            sig,
699            Signature::from_str("(so)").expect("Valid signature pattern")
700        );
701    }
702
703    #[test]
704    fn test_signal_body_signature_macro_with_interface_and_identifiers() {
705        let sig =
706            crate::signal_body_type_signature!(member: "AddNode", interface: "org.example.Node");
707        assert_eq!(
708            sig,
709            Signature::from_str("(so)").expect("Valid signature pattern")
710        );
711    }
712
713    #[test]
714    fn test_signal_body_signature_macro_with_argument_and_interface() {
715        let sig = crate::signal_body_type_signature!("Alert", "org.example.Node", "volume");
716        assert_eq!(
717            sig,
718            Signature::from_str("d").expect("Valid signature pattern")
719        );
720    }
721
722    #[test]
723    fn test_signal_body_signature_macro_with_argument_and_identifiers_and_interface() {
724        let sig = crate::signal_body_type_signature!(
725            member: "Alert",
726            interface: "org.example.Node",
727            argument: "urgent"
728        );
729        assert_eq!(
730            sig,
731            Signature::from_str("b").expect("Valid signature pattern")
732        );
733    }
734
735    #[test]
736    fn test_method_args_signature_macro() {
737        let sig = crate::method_args_signature!("RequestName");
738        assert_eq!(
739            sig,
740            Signature::from_str("(su)").expect("Valid signature pattern")
741        );
742    }
743
744    #[test]
745    fn test_method_args_signature_macro_with_identifier() {
746        let sig = crate::method_args_signature!(member: "RequestName");
747        assert_eq!(
748            sig,
749            Signature::from_str("(su)").expect("Valid signature pattern")
750        );
751    }
752
753    #[test]
754    fn test_method_args_signature_macro_with_interface() {
755        let sig = crate::method_args_signature!("RequestName", "org.example.Node");
756        assert_eq!(
757            sig,
758            Signature::from_str("(su)").expect("Valid signature pattern")
759        );
760    }
761
762    #[test]
763    fn test_method_args_signature_macro_with_interface_and_identifiers() {
764        let sig =
765            crate::method_args_signature!(member: "RequestName", interface: "org.example.Node");
766        assert_eq!(
767            sig,
768            Signature::from_str("(su)").expect("Valid signature pattern")
769        );
770    }
771
772    #[test]
773    fn test_method_args_signature_macro_with_argument_and_interface() {
774        let sig = crate::method_args_signature!("RequestName", "org.example.Node", "apple");
775        assert_eq!(
776            sig,
777            Signature::from_str("s").expect("Valid signature pattern")
778        );
779    }
780
781    #[test]
782    fn test_method_args_signature_macro_with_argument_and_identifiers_and_interface() {
783        let sig = crate::method_args_signature!(
784            member: "RequestName",
785            interface: "org.example.Node",
786            argument: "orange"
787        );
788        assert_eq!(
789            sig,
790            Signature::from_str("u").expect("Valid signature pattern")
791        );
792    }
793
794    #[test]
795    fn test_method_return_signature_macro() {
796        let sig = crate::method_return_signature!("RequestName");
797        assert_eq!(
798            sig,
799            Signature::from_str("u").expect("Valid signatuee pattern")
800        );
801    }
802
803    #[test]
804    fn test_method_return_signature_macro_with_identifier() {
805        let sig = crate::method_return_signature!(member: "RequestName");
806        assert_eq!(
807            sig,
808            Signature::from_str("u").expect("Valid signature pattern")
809        );
810    }
811
812    #[test]
813    fn test_method_return_signature_macro_with_interface() {
814        let sig = crate::method_return_signature!("RequestName", "org.example.Node");
815        assert_eq!(
816            sig,
817            Signature::from_str("u").expect("Valid signature pattern")
818        );
819    }
820
821    #[test]
822    fn test_method_return_signature_macro_with_interface_and_identifiers() {
823        let sig =
824            crate::method_return_signature!(member: "RequestName", interface: "org.example.Node");
825        assert_eq!(
826            sig,
827            Signature::from_str("u").expect("Vlaid signature pattern")
828        );
829    }
830
831    #[test]
832    fn test_method_return_signature_macro_with_argument_and_interface() {
833        let sig = crate::method_return_signature!("RequestName", "org.example.Node", "grape");
834        assert_eq!(
835            sig,
836            Signature::from_str("u").expect("Vlaid signature pattern")
837        );
838    }
839
840    #[test]
841    fn test_method_return_signature_macro_with_argument_and_identifiers_and_interface() {
842        let sig = crate::method_return_signature!(
843            member: "RequestName",
844            interface: "org.example.Node",
845            argument: "grape"
846        );
847        assert_eq!(
848            sig,
849            Signature::from_str("u").expect("Vlaid signature pattern")
850        );
851    }
852
853    #[test]
854    fn test_property_type_signature_macro() {
855        let sig = crate::property_type_signature!("Features");
856        assert_eq!(
857            sig,
858            Signature::from_str("as").expect("Vlaid signature pattern")
859        );
860    }
861
862    #[test]
863    fn test_property_type_signature_macro_with_identifier() {
864        let sig = crate::property_type_signature!(member: "Features");
865        assert_eq!(
866            sig,
867            Signature::from_str("as").expect("Vlaid signature pattern")
868        );
869    }
870
871    #[test]
872    fn test_property_type_signature_macro_with_interface() {
873        let sig = crate::property_type_signature!("Features", "org.example.Node");
874        assert_eq!(
875            sig,
876            Signature::from_str("as").expect("Vlaid signature pattern")
877        );
878    }
879
880    #[test]
881    fn test_property_type_signature_macro_with_interface_and_identifiers() {
882        let sig =
883            crate::property_type_signature!(member: "Features", interface: "org.example.Node");
884        assert_eq!(
885            sig,
886            Signature::from_str("as").expect("Vlaid signature pattern")
887        );
888    }
889}