Dbus: get properties through OrgFreedesktopDBusProperties

Hi,
I want to retrieve some properties using the dbus crate but the example at dbus-rs/properties.rs at master · diwic/dbus-rs · GitHub seems to not work correctly for my case.

The very skeleton code is:

fn main() {
  let mut conn = Connection::new_session().expect("D-Bus connection failed");
  let p = conn.with_proxy("X.Y.Z", "/X/Y/Z", Duration::from_millis(5000));
  let elapsed = p.get("X.Y.Z", "VAR");
  ...
}

Simply using dbus::blocking::stdintf::org_freedesktop_dbus::Properties as detailed in the example doesn't work for me:

error[E0283]: type annotations required: cannot resolve `for<'b> _: dbus::arg::Get<'b>`
   --> src/main.rs:169:21
    |
169 |     let elapsed = p.get("X.Y.Z", "VAR");
    |                     ^^^

error: aborting due to previous error

To have this working I had to use dbus-codegen-rust and basically copy and paste the output code for the org.freedesktop.DBus.Properties interface, that is:

pub trait OrgFreedesktopDBusProperties {
    fn get(&self, interface_name: &str, property_name: &str) -> Result<arg::Variant<Box<dyn arg::RefArg + 'static>>, dbus::Error>;
    fn get_all(&self, interface_name: &str) -> Result<::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>, dbus::Error>;
    fn set(&self, interface_name: &str, property_name: &str, value: arg::Variant<Box<dyn arg::RefArg>>) -> Result<(), dbus::Error>;
}

impl<'a, C: ::std::ops::Deref<Target=blocking::Connection>> OrgFreedesktopDBusProperties for blocking::Proxy<'a, C> {

    fn get(&self, interface_name: &str, property_name: &str) -> Result<arg::Variant<Box<dyn arg::RefArg + 'static>>, dbus::Error> {
        self.method_call("org.freedesktop.DBus.Properties", "Get", (interface_name, property_name, ))
            .and_then(|r: (arg::Variant<Box<dyn arg::RefArg + 'static>>, )| Ok(r.0, ))
    }

    fn get_all(&self, interface_name: &str) -> Result<::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>, dbus::Error> {
        self.method_call("org.freedesktop.DBus.Properties", "GetAll", (interface_name, ))
            .and_then(|r: (::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>, )| Ok(r.0, ))
    }

    fn set(&self, interface_name: &str, property_name: &str, value: arg::Variant<Box<dyn arg::RefArg>>) -> Result<(), dbus::Error> {
        self.method_call("org.freedesktop.DBus.Properties", "Set", (interface_name, property_name, value, ))
    }
}

What am I doing wrong here?

Solved with:

let elapsed: &dyn arg::RefArg = &(proxy.get("X.Y.Z", "Elapsed")
     as Result<Box<dyn arg::RefArg + 'static>, dbus::Error>)?;

Let me know if there is any better way to do this :wink:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.