簡體   English   中英

使用Rust DBUS庫時,不滿足特性綁定`dbus :: arg :: Get`

[英]The trait bound `dbus::arg::Get` is not satisfied when using the Rust DBUS library

我正在嘗試使用dbus-rs庫使用GetSettings方法從NetworkManager獲取連接信息。 我用D-Feet試用了具有GetSettings() -> (Dict of {String, Dict of {String, Variant} } settings)的函數,D-Feet返回的數據如下:

{'802-11-wireless': {'mac-address': [228, 179, 24, 77, 64, 139],
                     'mac-address-blacklist': [],
                     'mode': 'infrastructure',
                     'security': '802-11-wireless-security',
                     'seen-bssids': ['02:1D:AA:80:1B:DA', '02:1D:AA:80:1D:12'],
                     'ssid': [80,
                              108,
                              111,
                              117,
                              103,
                              104,
                              32,
                              87,
                              97,
                              121,
                              32,
                              67,
                              97,
                              102,
                              101]},
 '802-11-wireless-security': {'auth-alg': 'open',
                              'group': [],
                              'key-mgmt': 'wpa-psk',
                              'pairwise': [],
                              'proto': []},
 'connection': {'id': 'Plough Way Cafe',
                'permissions': [],
                'secondaries': [],
                'timestamp': 1479304123,
                'type': '802-11-wireless',
                'uuid': 'ff9b7028-0911-491a-bfe8-53cba76069da'},
 'ipv4': {'address-data': [],
          'addresses': [],
          'dns': [],
          'dns-search': [],
          'method': 'auto',
          'route-data': [],
          'routes': []},
 'ipv6': {'address-data': [],
          'addresses': [],
          'dns': [],
          'dns-search': [],
          'method': 'auto',
          'route-data': [],
          'routes': []}}

和我的代碼:

extern crate dbus;

fn main() {
    let message = dbus::Message::new_method_call("org.freedesktop.NetworkManager",
                                                 "/org/freedesktop/NetworkManager/Settings/0",
                                                 "org.freedesktop.NetworkManager.Settings.\
                                                  Connection",
                                                 "GetSettings")
        .unwrap();

    let response = dbus::Connection::get_private(dbus::BusType::System)
        .unwrap()
        .send_with_reply_and_block(message, 2000)
        .unwrap();

    println!("{:?}", response);

    let test: dbus::arg::Dict<&str, dbus::arg::Dict<&str, dbus::arg::Variant<()>, _>, _> =
        response.get1().unwrap();

    println!("{:?}", test);
}

這會導致此錯誤:

error[E0277]: the trait bound `(): dbus::arg::Get<'_>` is not satisfied
  --> src/main.rs:20:18
   |
20 |         response.get1().unwrap();
   |                  ^^^^ the trait `dbus::arg::Get<'_>` is not implemented for `()`
   |
   = note: required because of the requirements on the impl of `dbus::arg::Get<'_>` for `dbus::arg::Variant<()>`
   = note: required because of the requirements on the impl of `dbus::arg::Get<'_>` for `dbus::arg::Dict<'_, &str, dbus::arg::Variant<()>, dbus::arg::Iter<'_>>`
   = note: required because of the requirements on the impl of `dbus::arg::Get<'_>` for `dbus::arg::Dict<'_, &str, dbus::arg::Dict<'_, &str, dbus::arg::Variant<()>, dbus::arg::Iter<'_>>,     dbus::arg::Iter<'_>>`

我怎樣才能獲得連接信息?

我認為Variant的重點在於它可以容納不同類型的數據嗎? 我究竟做錯了什么?

如果我用&str替換Variant類型() ,它會輸出Dict(Iter("Unknown?!", "Unknown?!", "Unknown?!", "Unknown?!", "Unknown?!"), PhantomData) 什么是Unknown?! 值?

DictAPI也說明了

從迭代器創建一個新的Dict 附加時會消耗迭代器。

我應該如何/應該使用它? 我確實設法取得了一些進展,也許是天真的?

我的代碼現在看起來像這樣:

extern crate dbus;
extern crate network_manager;

#[derive(Default, Debug)]
struct Connection {
    path: String,
    id: String,
    uuid: String,
    ssid: String,
    interface: String,
    security: String,
    psk: String, // Only used when creating a new connection
}

fn main() {
    let connection = Connection {
        path: "/org/freedesktop/NetworkManager/Settings/0".to_string(),
        ..Default::default()
    };

    let message = dbus::Message::new_method_call("org.freedesktop.NetworkManager",
                                                 connection.path.clone(),
                                                 "org.freedesktop.NetworkManager.Settings.\
                                                  Connection",
                                                 "GetSettings")
        .unwrap();

    let response = dbus::Connection::get_private(dbus::BusType::System)
        .unwrap()
        .send_with_reply_and_block(message, 2000)
        .unwrap();

    let mut outer_array_iter = response.iter_init().recurse(97).unwrap();
    loop {
        let mut outer_dict_iter = outer_array_iter.recurse(101).unwrap();
        outer_dict_iter.next();

        let mut inner_array_iter = outer_dict_iter.recurse(97).unwrap();
        loop {
            let mut inner_dict_iter = inner_array_iter.recurse(101).unwrap();

            let key = inner_dict_iter.read::<&str>().unwrap();
            match key {
                "id" => {
                    let val: dbus::arg::Variant<&str> = inner_dict_iter.read().unwrap();
                    println!("id {:?}", val);
                }
                "uuid" => {
                    let val: dbus::arg::Variant<&str> = inner_dict_iter.read().unwrap();
                    println!("uuid {:?}", val);
                }
                "ssid" => {
                    let val: dbus::arg::Variant<dbus::arg::Array<i32, _>> = inner_dict_iter.read()
                        .unwrap();
                    println!("ssid {:?}", val);
                }
                "type" => {
                    let val: dbus::arg::Variant<&str> = inner_dict_iter.read().unwrap();
                    println!("interface {:?}", val);
                }
                "security" => {
                    let val: dbus::arg::Variant<&str> = inner_dict_iter.read().unwrap();
                    println!("security {:?}", val);
                }
                _ => (),
            }

            if !(inner_array_iter.next()) {
                break;
            }
        }

        if !(outer_array_iter.next()) {
            break;
        }
    }

    println!("{:?}", connection);
}

打印出來:

id Variant("Plough Way Cafe")
uuid Variant("e078808e-626f-4be9-bbb4-5e48b1d626de")
interface Variant("802-11-wireless")
ssid Variant(Array(Iter("u8", "u8", "u8", "u8", "u8", "u8", "u8", "u8"), PhantomData))
security Variant("802-11-wireless-security")
Connection { path: "/org/freedesktop/NetworkManager/Settings/0", id: "", uuid: "", ssid: "", interface: "", security: "", psk: "" }

如何從Variant和我的connection結構中獲取數據? 有沒有更好的方法來使用迭代器,因為這感覺非常脆弱?

以下是修改第一個示例的方法:

let test: dbus::arg::Dict<&str, dbus::arg::Dict<&str, dbus::arg::Variant<dbus::arg::Iter>, _>, _> =
response.get1().unwrap();

for (k1, v1) in test {
    println!("outer key = {:?}", k1);
    for (k2, v2) in v1 {
        println!("    inner key = {:?}, inner type = {:?}, string value = {:?}", k2, v2, v2.0.clone().get::<&str>());
    }
}

你需要使用Variant<Iter>如果你不知道你的變種里面有什么。 然后,您必須使用get::<&str>(), get::<u32>()等來檢索變體中的實際值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM