pub struct Factory<M: MethodType<D>, D: DataType = ()>(/* private fields */);
Expand description
The factory is used to create object paths, interfaces, methods etc.
There are three factories:
MTFn - all methods are Fn()
.
MTFnMut - all methods are FnMut()
. This means they can mutate their environment,
which has the side effect that if you call it recursively, it will RefCell panic.
MTSync - all methods are Fn() + Send + Sync + 'static
. This means that the methods
can be called from different threads in parallel.
Implementations§
Source§impl Factory<MTFn<()>, ()>
impl Factory<MTFn<()>, ()>
Sourcepub fn new_fn<D: DataType>() -> Factory<MTFn<D>, D>
pub fn new_fn<D: DataType>() -> Factory<MTFn<D>, D>
Creates a new factory for single-thread use.
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}
More examples
57fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 // The online property can be both set and get
64 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 // The "checking" property is read only
82 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 // ...and so is the "description" property
91 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 // ...add a method for starting a device check...
100 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 // Start some lengthy processing in a separate thread...
111 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 // Bogus check of device
116 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 // Tell main thread that we finished
120 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 // Indicate that we send a special signal once checking has completed.
125 .add_s(check_complete.clone())
126 , check_complete)
127}
128
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}
Source§impl<D: DataType> Factory<MTFn<D>, D>
impl<D: DataType> Factory<MTFn<D>, D>
Sourcepub fn method<H, T>(
&self,
t: T,
data: D::Method,
handler: H,
) -> Method<MTFn<D>, D>
pub fn method<H, T>( &self, t: T, data: D::Method, handler: H, ) -> Method<MTFn<D>, D>
Creates a new method for single-thread use.
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}
More examples
57fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 // The online property can be both set and get
64 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 // The "checking" property is read only
82 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 // ...and so is the "description" property
91 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 // ...add a method for starting a device check...
100 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 // Start some lengthy processing in a separate thread...
111 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 // Bogus check of device
116 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 // Tell main thread that we finished
120 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 // Indicate that we send a special signal once checking has completed.
125 .add_s(check_complete.clone())
126 , check_complete)
127}
Source§impl<M: MethodType<D>, D: DataType> Factory<M, D>
impl<M: MethodType<D>, D: DataType> Factory<M, D>
Sourcepub fn property<A: Arg, T: Into<String>>(
&self,
name: T,
data: D::Property,
) -> Property<M, D>
pub fn property<A: Arg, T: Into<String>>( &self, name: T, data: D::Property, ) -> Property<M, D>
Creates a new property.
A
is used to calculate the type signature of the property.
Examples found in repository?
57fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 // The online property can be both set and get
64 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 // The "checking" property is read only
82 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 // ...and so is the "description" property
91 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 // ...add a method for starting a device check...
100 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 // Start some lengthy processing in a separate thread...
111 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 // Bogus check of device
116 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 // Tell main thread that we finished
120 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 // Indicate that we send a special signal once checking has completed.
125 .add_s(check_complete.clone())
126 , check_complete)
127}
Sourcepub fn signal<T: Into<Member<'static>>>(
&self,
name: T,
data: D::Signal,
) -> Signal<D>
pub fn signal<T: Into<Member<'static>>>( &self, name: T, data: D::Signal, ) -> Signal<D>
Creates a new signal.
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}
More examples
57fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 // The online property can be both set and get
64 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 // The "checking" property is read only
82 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 // ...and so is the "description" property
91 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 // ...add a method for starting a device check...
100 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 // Start some lengthy processing in a separate thread...
111 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 // Bogus check of device
116 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 // Tell main thread that we finished
120 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 // Indicate that we send a special signal once checking has completed.
125 .add_s(check_complete.clone())
126 , check_complete)
127}
Sourcepub fn interface<T: Into<IfaceName<'static>>>(
&self,
name: T,
data: D::Interface,
) -> Interface<M, D>
pub fn interface<T: Into<IfaceName<'static>>>( &self, name: T, data: D::Interface, ) -> Interface<M, D>
Creates a new interface.
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}
More examples
57fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 // The online property can be both set and get
64 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 // The "checking" property is read only
82 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 // ...and so is the "description" property
91 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 // ...add a method for starting a device check...
100 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 // Start some lengthy processing in a separate thread...
111 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 // Bogus check of device
116 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 // Tell main thread that we finished
120 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 // Indicate that we send a special signal once checking has completed.
125 .add_s(check_complete.clone())
126 , check_complete)
127}
Sourcepub fn object_path<T: Into<Path<'static>>>(
&self,
name: T,
data: D::ObjectPath,
) -> ObjectPath<M, D>
pub fn object_path<T: Into<Path<'static>>>( &self, name: T, data: D::ObjectPath, ) -> ObjectPath<M, D>
Creates a new object path.
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 tree(&self, data: D::Tree) -> Tree<M, D>
pub fn tree(&self, data: D::Tree) -> Tree<M, D>
Creates a new 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 method_sync<H, T>(
&self,
t: T,
data: D::Method,
handler: H,
) -> Method<M, D>where
H: Fn(&MethodInfo<'_, M, D>) -> MethodResult + Send + Sync + 'static,
T: Into<Member<'static>>,
pub fn method_sync<H, T>(
&self,
t: T,
data: D::Method,
handler: H,
) -> Method<M, D>where
H: Fn(&MethodInfo<'_, M, D>) -> MethodResult + Send + Sync + 'static,
T: Into<Member<'static>>,
Creates a new method - usually you’ll use “method” instead.
This is useful for being able to create methods in code which is generic over methodtype.