pub struct Interface<M: MethodType<D>, D: DataType> { /* private fields */ }
Expand description
Represents a D-Bus interface.
Implementations§
Source§impl<M: MethodType<D>, D: DataType> Interface<M, D>
impl<M: MethodType<D>, D: DataType> Interface<M, D>
Sourcepub fn add_m<I: Into<Arc<Method<M, D>>>>(self, m: I) -> Self
pub fn add_m<I: Into<Arc<Method<M, D>>>>(self, m: I) -> Self
Builder function that adds a method to the interface.
Examples found in repository?
examples/server.rs (lines 34-59)
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
examples/adv_server.rs (lines 100-123)
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 add_s<I: Into<Arc<Signal<D>>>>(self, s: I) -> Self
pub fn add_s<I: Into<Arc<Signal<D>>>>(self, s: I) -> Self
Builder function that adds a signal to the interface.
Examples found in repository?
examples/server.rs (line 59)
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
examples/adv_server.rs (line 125)
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 add_p<I: Into<Arc<Property<M, D>>>>(self, p: I) -> Self
pub fn add_p<I: Into<Arc<Property<M, D>>>>(self, p: I) -> Self
Builder function that adds a property to the interface.
Examples found in repository?
examples/adv_server.rs (lines 64-80)
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 annotate<N: Into<String>, V: Into<String>>(
self,
name: N,
value: V,
) -> Self
pub fn annotate<N: Into<String>, V: Into<String>>( self, name: N, value: V, ) -> Self
Builder function that adds an annotation to this interface.
Sourcepub fn deprecated(self) -> Self
pub fn deprecated(self) -> Self
Builder function that adds an annotation that this entity is deprecated.
Sourcepub fn get_name(&self) -> &IfaceName<'static>
pub fn get_name(&self) -> &IfaceName<'static>
Get interface name
Examples found in repository?
examples/server.rs (line 47)
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 iter_m<'a>(&'a self) -> Iter<'a, Method<M, D>> ⓘ
pub fn iter_m<'a>(&'a self) -> Iter<'a, Method<M, D>> ⓘ
Iterates over methods implemented by this interface.
Trait Implementations§
Auto Trait Implementations§
impl<M, D> Freeze for Interface<M, D>
impl<M, D> RefUnwindSafe for Interface<M, D>where
<D as DataType>::Interface: RefUnwindSafe,
<D as DataType>::Method: RefUnwindSafe,
<D as DataType>::Signal: RefUnwindSafe,
<D as DataType>::Property: RefUnwindSafe,
<M as MethodType<D>>::Method: RefUnwindSafe,
<M as MethodType<D>>::GetProp: RefUnwindSafe,
<M as MethodType<D>>::SetProp: RefUnwindSafe,
impl<M, D> Send for Interface<M, D>
impl<M, D> Sync for Interface<M, D>
impl<M, D> Unpin for Interface<M, D>
impl<M, D> UnwindSafe for Interface<M, D>where
<D as DataType>::Interface: UnwindSafe,
<D as DataType>::Method: RefUnwindSafe,
<D as DataType>::Signal: RefUnwindSafe,
<D as DataType>::Property: RefUnwindSafe,
<M as MethodType<D>>::Method: RefUnwindSafe,
<M as MethodType<D>>::GetProp: RefUnwindSafe,
<M as MethodType<D>>::SetProp: RefUnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more