pub struct Tree<M: MethodType<D>, D: DataType> { /* private fields */ }
Expand description
A collection of object paths.
Implementations§
Source§impl<M: MethodType<D>, D: DataType> Tree<M, D>
impl<M: MethodType<D>, D: DataType> Tree<M, D>
Sourcepub fn add<I: Into<Arc<ObjectPath<M, D>>>>(self, s: I) -> Self
pub fn add<I: Into<Arc<ObjectPath<M, D>>>>(self, s: I) -> Self
Builder function that adds an object path to this tree.
Examples found in repository?
129fn create_tree(devices: &[Arc<Device>], iface: &Arc<Interface<MTFn<TData>, TData>>)
130 -> tree::Tree<MTFn<TData>, TData> {
131
132 let f = tree::Factory::new_fn();
133 let mut tree = f.tree(());
134 for dev in devices {
135 tree = tree.add(f.object_path(dev.path.clone(), dev.clone())
136 .introspectable()
137 .add(iface.clone())
138 );
139 }
140 tree
141}
More examples
16fn main() -> Result<(), Box<dyn Error>> {
17 // Let's start by starting up a connection to the session bus and request a name.
18 let c = LocalConnection::new_session()?;
19 c.request_name("com.example.dbustest", false, true, false)?;
20
21 // The choice of factory tells us what type of tree we want,
22 // and if we want any extra data inside. We pick the simplest variant.
23 let f = Factory::new_fn::<()>();
24
25 // We create the signal first, since we'll need it in both inside the method callback
26 // and when creating the tree.
27 let signal = Arc::new(f.signal("HelloHappened", ()).sarg::<&str,_>("sender"));
28 let signal2 = signal.clone();
29
30 // We create a tree with one object path inside and make that path introspectable.
31 let tree = f.tree(()).add(f.object_path("/hello", ()).introspectable().add(
32
33 // We add an interface to the object path...
34 f.interface("com.example.dbustest", ()).add_m(
35
36 // ...and a method inside the interface.
37 f.method("Hello", (), move |m| {
38
39 // This is the callback that will be called when another peer on the bus calls our method.
40 // the callback receives "MethodInfo" struct and can return either an error, or a list of
41 // messages to send back.
42
43 let name: &str = m.msg.read1()?;
44 let s = format!("Hello {}!", name);
45 let mret = m.msg.method_return().append1(s);
46
47 let sig = signal.msg(m.path.get_name(), m.iface.get_name())
48 .append1(&*name);
49
50 // Two messages will be returned - one is the method return (and should always be there),
51 // and in our case we also have a signal we want to send at the same time.
52 Ok(vec!(mret, sig))
53
54 // Our method has one output argument and one input argument.
55 }).outarg::<&str,_>("reply")
56 .inarg::<&str,_>("name")
57
58 // We also add the signal to the interface. This is mainly for introspection.
59 ).add_s(signal2)
60
61 // Also add the root path, to help introspection from debugging tools.
62 )).add(f.object_path("/", ()).introspectable());
63
64 // We add the tree to the connection so that incoming method calls will be handled.
65 tree.start_receive(&c);
66
67 // Serve clients forever.
68 loop { c.process(Duration::from_millis(1000))?; }
69}
Sourcepub fn get(&self, p: &Path<'static>) -> Option<&Arc<ObjectPath<M, D>>>
pub fn get(&self, p: &Path<'static>) -> Option<&Arc<ObjectPath<M, D>>>
Get a reference to an object path from the tree.
Sourcepub fn iter<'a>(&'a self) -> Iter<'a, ObjectPath<M, D>> ⓘ
pub fn iter<'a>(&'a self) -> Iter<'a, ObjectPath<M, D>> ⓘ
Iterates over object paths in this tree.
Sourcepub fn insert<I: Into<Arc<ObjectPath<M, D>>>>(&mut self, s: I)
pub fn insert<I: Into<Arc<ObjectPath<M, D>>>>(&mut self, s: I)
Non-builder function that adds an object path to this tree.
Sourcepub fn remove(&mut self, p: &Path<'static>) -> Option<Arc<ObjectPath<M, D>>>
pub fn remove(&mut self, p: &Path<'static>) -> Option<Arc<ObjectPath<M, D>>>
Remove a object path from the Tree. Returns the object path removed, or None if not found.
Sourcepub fn set_registered(&self, c: &Connection, b: bool) -> Result<(), Error>
pub fn set_registered(&self, c: &Connection, b: bool) -> Result<(), Error>
Registers or unregisters all object paths in the tree to a ffidisp::Connection.
Examples found in repository?
143fn run() -> Result<(), Box<dyn std::error::Error>> {
144 // Create our bogus devices
145 let devices: Vec<Arc<Device>> = (0..10).map(|i| Arc::new(Device::new_bogus(i))).collect();
146
147 // Create tree
148 let (check_complete_s, check_complete_r) = mpsc::channel::<i32>();
149 let (iface, sig) = create_iface(check_complete_s);
150 let tree = create_tree(&devices, &Arc::new(iface));
151
152 // Setup DBus connection
153 let c = Connection::new_session()?;
154 c.register_name("com.example.dbus.rs.advancedserverexample", 0)?;
155 tree.set_registered(&c, true)?;
156
157 // ...and serve incoming requests.
158 c.add_handler(tree);
159 loop {
160 // Wait for incoming messages. This will block up to one second.
161 // Discard the result - relevant messages have already been handled.
162 c.incoming(1000).next();
163
164 // Do all other things we need to do in our main loop.
165 if let Ok(idx) = check_complete_r.try_recv() {
166 let dev = &devices[idx as usize];
167 dev.checking.set(false);
168 c.send(sig.msg(&dev.path, &"com.example.dbus.rs.device".into())).map_err(|_| "Sending DBus signal failed")?;
169 }
170 }
171}
Sourcepub fn run<'a, I: Iterator<Item = ConnectionItem>>(
&'a self,
c: &'a Connection,
i: I,
) -> TreeServer<'a, I, M, D> ⓘ
pub fn run<'a, I: Iterator<Item = ConnectionItem>>( &'a self, c: &'a Connection, i: I, ) -> TreeServer<'a, I, M, D> ⓘ
This method takes an ConnectionItem
iterator (you get it from Connection::iter()
)
and handles all matching items. Non-matching items (e g signals) are passed through.
Sourcepub fn handle(&self, m: &Message) -> Option<Vec<Message>>
pub fn handle(&self, m: &Message) -> Option<Vec<Message>>
Handles a message.
Will return None in case the object path was not found in this tree, or otherwise a list of messages to be sent back.
Source§impl<M: MethodType<D> + 'static, D: DataType + 'static> Tree<M, D>
impl<M: MethodType<D> + 'static, D: DataType + 'static> Tree<M, D>
Sourcepub fn start_receive_sync<C>(self, connection: &C)where
C: MatchingReceiver<F = Box<dyn FnMut(Message, &C) -> bool + Send + Sync>> + Sender,
D::Tree: Send + Sync,
D::ObjectPath: Send + Sync,
D::Interface: Send + Sync,
D::Property: Send + Sync,
D::Method: Send + Sync,
D::Signal: Send + Sync,
M::Method: Send + Sync,
M::GetProp: Send + Sync,
M::SetProp: Send + Sync,
pub fn start_receive_sync<C>(self, connection: &C)where
C: MatchingReceiver<F = Box<dyn FnMut(Message, &C) -> bool + Send + Sync>> + Sender,
D::Tree: Send + Sync,
D::ObjectPath: Send + Sync,
D::Interface: Send + Sync,
D::Property: Send + Sync,
D::Method: Send + Sync,
D::Signal: Send + Sync,
M::Method: Send + Sync,
M::GetProp: Send + Sync,
M::SetProp: Send + Sync,
Connects a SyncConnection with a Tree so that incoming method calls are handled.
The tree needs to be of type MTSync.
Sourcepub fn start_receive_send<C>(self, connection: &C)where
C: MatchingReceiver<F = Box<dyn FnMut(Message, &C) -> bool + Send>> + Sender,
D::Tree: Send + Sync,
D::ObjectPath: Send + Sync,
D::Interface: Send + Sync,
D::Property: Send + Sync,
D::Method: Send + Sync,
D::Signal: Send + Sync,
M::Method: Send + Sync,
M::GetProp: Send + Sync,
M::SetProp: Send + Sync,
pub fn start_receive_send<C>(self, connection: &C)where
C: MatchingReceiver<F = Box<dyn FnMut(Message, &C) -> bool + Send>> + Sender,
D::Tree: Send + Sync,
D::ObjectPath: Send + Sync,
D::Interface: Send + Sync,
D::Property: Send + Sync,
D::Method: Send + Sync,
D::Signal: Send + Sync,
M::Method: Send + Sync,
M::GetProp: Send + Sync,
M::SetProp: Send + Sync,
Connects a Connection with a Tree so that incoming method calls are handled.
The tree needs to be of type MTSync.
Sourcepub fn start_receive<C>(self, connection: &C)
pub fn start_receive<C>(self, connection: &C)
Connects a LocalConnection with a Tree so that incoming method calls are handled.
Examples found in repository?
16fn main() -> Result<(), Box<dyn Error>> {
17 // Let's start by starting up a connection to the session bus and request a name.
18 let c = LocalConnection::new_session()?;
19 c.request_name("com.example.dbustest", false, true, false)?;
20
21 // The choice of factory tells us what type of tree we want,
22 // and if we want any extra data inside. We pick the simplest variant.
23 let f = Factory::new_fn::<()>();
24
25 // We create the signal first, since we'll need it in both inside the method callback
26 // and when creating the tree.
27 let signal = Arc::new(f.signal("HelloHappened", ()).sarg::<&str,_>("sender"));
28 let signal2 = signal.clone();
29
30 // We create a tree with one object path inside and make that path introspectable.
31 let tree = f.tree(()).add(f.object_path("/hello", ()).introspectable().add(
32
33 // We add an interface to the object path...
34 f.interface("com.example.dbustest", ()).add_m(
35
36 // ...and a method inside the interface.
37 f.method("Hello", (), move |m| {
38
39 // This is the callback that will be called when another peer on the bus calls our method.
40 // the callback receives "MethodInfo" struct and can return either an error, or a list of
41 // messages to send back.
42
43 let name: &str = m.msg.read1()?;
44 let s = format!("Hello {}!", name);
45 let mret = m.msg.method_return().append1(s);
46
47 let sig = signal.msg(m.path.get_name(), m.iface.get_name())
48 .append1(&*name);
49
50 // Two messages will be returned - one is the method return (and should always be there),
51 // and in our case we also have a signal we want to send at the same time.
52 Ok(vec!(mret, sig))
53
54 // Our method has one output argument and one input argument.
55 }).outarg::<&str,_>("reply")
56 .inarg::<&str,_>("name")
57
58 // We also add the signal to the interface. This is mainly for introspection.
59 ).add_s(signal2)
60
61 // Also add the root path, to help introspection from debugging tools.
62 )).add(f.object_path("/", ()).introspectable());
63
64 // We add the tree to the connection so that incoming method calls will be handled.
65 tree.start_receive(&c);
66
67 // Serve clients forever.
68 loop { c.process(Duration::from_millis(1000))?; }
69}