Struct Interface

Source
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>

Source

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
Hide additional 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}
Source

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
Hide additional 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}
Source

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}
Source

pub fn annotate<N: Into<String>, V: Into<String>>( self, name: N, value: V, ) -> Self

Builder function that adds an annotation to this interface.

Source

pub fn deprecated(self) -> Self

Builder function that adds an annotation that this entity is deprecated.

Source

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}
Source

pub fn get_data(&self) -> &D::Interface

Get associated data

Source

pub fn iter_m<'a>(&'a self) -> Iter<'a, Method<M, D>>

Iterates over methods implemented by this interface.

Source

pub fn iter_s<'a>(&'a self) -> Iter<'a, Signal<D>>

Iterates over signals implemented by this interface.

Source

pub fn iter_p<'a>(&'a self) -> Iter<'a, Property<M, D>>

Iterates over properties implemented by this interface.

Trait Implementations§

Source§

impl<M: Debug + MethodType<D>, D: Debug + DataType> Debug for Interface<M, D>
where D::Interface: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<M, D> Freeze for Interface<M, D>
where <D as DataType>::Interface: Freeze,

§

impl<M, D> RefUnwindSafe for Interface<M, D>

§

impl<M, D> Send for Interface<M, D>
where <D as DataType>::Interface: Send, <D as DataType>::Method: Sync + Send, <D as DataType>::Signal: Sync + Send, <D as DataType>::Property: Sync + Send, <M as MethodType<D>>::Method: Sync + Send, <M as MethodType<D>>::GetProp: Sync + Send, <M as MethodType<D>>::SetProp: Sync + Send,

§

impl<M, D> Sync for Interface<M, D>
where <D as DataType>::Interface: Sync, <D as DataType>::Method: Sync + Send, <D as DataType>::Signal: Sync + Send, <D as DataType>::Property: Sync + Send, <M as MethodType<D>>::Method: Sync + Send, <M as MethodType<D>>::GetProp: Sync + Send, <M as MethodType<D>>::SetProp: Sync + Send,

§

impl<M, D> Unpin for Interface<M, D>
where <D as DataType>::Interface: Unpin,

§

impl<M, D> UnwindSafe for Interface<M, D>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.