gio/
dbus_interface_info.rs1use std::ffi::CStr;
4
5use crate::ffi;
6use crate::{DBusInterfaceInfo, DBusPropertyInfo};
7use glib::translate::*;
8
9impl DBusInterfaceInfo {
10 pub fn name(&self) -> &str {
11 unsafe {
12 let c_obj = self.as_ptr();
13 let name = (*c_obj).name;
14 assert!(!name.is_null());
15 let c_str = CStr::from_ptr(name);
16 c_str.to_str().unwrap()
17 }
18 }
19
20 pub fn properties(&self) -> DBusInterfaceInfoPropertiesIter<'_> {
21 DBusInterfaceInfoPropertiesIter::new(self)
22 }
23}
24
25pub struct DBusInterfaceInfoPropertiesIter<'a> {
26 _stash: Stash<'a, *mut ffi::GDBusInterfaceInfo, DBusInterfaceInfo>,
27 next_property: *mut *mut ffi::GDBusPropertyInfo,
28}
29
30impl<'a> DBusInterfaceInfoPropertiesIter<'a> {
31 fn new(info: &'a DBusInterfaceInfo) -> Self {
32 let stash: Stash<*mut ffi::GDBusInterfaceInfo, _> = info.to_glib_none();
33 let next_property = unsafe { *stash.0 }.properties;
38 Self {
39 _stash: stash,
40 next_property,
41 }
42 }
43}
44
45impl<'a> Iterator for DBusInterfaceInfoPropertiesIter<'a> {
46 type Item = DBusPropertyInfo;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 unsafe {
52 assert!(!self.next_property.is_null());
53 let property = *self.next_property;
54 if !property.is_null() {
55 self.next_property = self.next_property.add(1);
56 Some(from_glib_none(property))
57 } else {
58 None
59 }
60 }
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use crate::DBusNodeInfo;
67
68 #[test]
69 fn iterate_properties() {
70 const XML: &str = r#"
71 <node>
72 <interface name='com.github.gtk_rs.Test'>
73 <property name='Name' type='s' access='read' />
74 <property name='Count' type='x' access='write' />
75 </interface>
76 </node>
77 "#;
78 let node_info = DBusNodeInfo::for_xml(XML).unwrap();
79 let interface = node_info
80 .lookup_interface("com.github.gtk_rs.Test")
81 .unwrap();
82
83 let mut properties = interface.properties();
84 let property = properties.next().unwrap();
85 assert_eq!("Name", property.name());
86 let property = properties.next().unwrap();
87 assert_eq!("Count", property.name());
88 assert!(properties.next().is_none());
89 }
90
91 #[test]
92 fn iterate_empty_properties() {
93 const XML: &str = r#"
94 <node>
95 <interface name='com.github.gtk_rs.Test' />
96 </node>
97 "#;
98 let node_info = DBusNodeInfo::for_xml(XML).unwrap();
99 let interface = node_info
100 .lookup_interface("com.github.gtk_rs.Test")
101 .unwrap();
102
103 let mut properties = interface.properties();
104 assert!(properties.next().is_none());
105 }
106
107 #[test]
108 fn iterator_is_sealed() {
109 const XML: &str = r#"
110 <node>
111 <interface name='com.github.gtk_rs.Test'>
112 <property name='Count' type='x' access='write' />
113 </interface>
114 </node>
115 "#;
116 let node_info = DBusNodeInfo::for_xml(XML).unwrap();
117 let interface = node_info
118 .lookup_interface("com.github.gtk_rs.Test")
119 .unwrap();
120
121 let mut properties = interface.properties();
122 let _property = properties.next().unwrap();
123 assert!(properties.next().is_none());
124
125 assert!(properties.next().is_none());
126 }
127}