4

I want to list all the available block devices in the system using a dbus implementation called zbus.

The UDisks2 documentation mentions a method call on org.freedesktop.UDisks2.Manager interface called GetBlockDevices which accepts IN a{sv} options, OUT ao block_objects for method parameters.

Using zbus, I write:

use std::error::Error;
use std::result::Result;
use zbus::{Connection, Proxy};

fn main() -> Result<(), Box<dyn Error>> {
    let connection = Connection::new_system()?;
    let p = Proxy::new(
        &connection,
        "org.freedesktop.UDisks2",
        "/org/freedesktop/UDisks2/Manager",
        "org.freedesktop.UDisks2.Manager",
    )?;
    let resp: Vec<zvariant::ObjectPath> = p.call("GetBlockDevices", &std::collections::HashMap::<String, zvariant::Value>::new())?;
    dbg!(resp);
    Ok(())
}

As far as I understand, zvariant Values represent a DBus Variant. However I get the following error:

error: implementation of `serde::de::Deserialize` is not general enough
   --> src/main.rs:13:45
    |
13  |       let resp: Vec<zvariant::ObjectPath> = p.call("GetBlockDevices", &std::collections::HashMap::<String, zvariant::Value>::new())?;
    |                                               ^^^^ implementation of `serde::de::Deserialize` is not general enough
    | 
   ::: /home/adnan338/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.115/src/de/mod.rs:531:1
    |
531 | / pub trait Deserialize<'de>: Sized {
532 | |     /// Deserialize this value from the given Serde deserializer.
533 | |     ///
534 | |     /// See the [Implementing `Deserialize`][impl-deserialize] section of the
...   |
569 | |     }
570 | | }
    | |_- trait `serde::de::Deserialize` defined here
    |
    = note: `std::vec::Vec<zvariant::object_path::ObjectPath<'_>>` must implement `serde::de::Deserialize<'0>`, for any lifetime `'0`...
    = note: ...but `std::vec::Vec<zvariant::object_path::ObjectPath<'_>>` actually implements `serde::de::Deserialize<'1>`, for some specific lifetime `'1`

What's causing this and how can I avoid this error?

1 Answer 1

3

Firstly, thanks for trying out our crate. The issue is that zbus::Proxy::call expects the return value to be an owned one, while you're deserializing to an unowned type. Both of the the following work:

// OwnedObjectPath require zvariant >= 2.2.0
let resp: Vec<zvariant::OwnedObjectPath> = p.call(
    "GetBlockDevices",
    &std::collections::HashMap::<String, zvariant::Value>::new(),
)?;
let resp = p.call_method(
    "GetBlockDevices",
    &std::collections::HashMap::<String, zvariant::Value>::new(),
)?; 
let resp: Vec<zvariant::ObjectPath> = resp.body()?;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.