1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use super::{Connection, Message, MessageItem, Error};
use std::collections::BTreeMap;
pub struct Props<'a> {
name: String,
path: String,
interface: String,
timeout_ms: i32,
conn: &'a Connection,
}
impl<'a> Props<'a> {
pub fn new(conn: &'a Connection, name: &str, path: &str, interface: &str, timeout_ms: i32) -> Props<'a> {
Props {
name: name.to_string(),
path: path.to_string(),
interface: interface.to_string(),
timeout_ms: timeout_ms,
conn: conn,
}
}
pub fn get(&self, propname: &str) -> Result<MessageItem, Error> {
let mut m = Message::new_method_call(&self.name, &self.path,
"org.freedesktop.DBus.Properties", "Get").unwrap();
m.append_items(&[self.interface.clone().into(), propname.to_string().into()]);
let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
let reply = try!(r.as_result()).get_items();
if reply.len() == 1 {
if let &MessageItem::Variant(ref v) = &reply[0] {
return Ok((**v).clone())
}
}
let f = format!("Invalid reply for property get {}: '{:?}'", propname, reply);
return Err(Error::new_custom("InvalidReply", &f));
}
pub fn set(&self, propname: &str, value: MessageItem) -> Result<(), Error> {
let mut m = Message::new_method_call(&self.name, &self.path,
"org.freedesktop.DBus.Properties", "Set").unwrap();
m.append_items(&[self.interface.clone().into(), propname.to_string().into(), Box::new(value).into()]);
let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
try!(r.as_result());
Ok(())
}
pub fn get_all(&self) -> Result<BTreeMap<String, MessageItem>, Error> {
let mut m = Message::new_method_call(&self.name, &self.path,
"org.freedesktop.DBus.Properties", "GetAll").unwrap();
m.append_items(&[self.interface.clone().into()]);
let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
let reply = try!(r.as_result()).get_items();
(|| {
if reply.len() != 1 { return Err(()) };
let mut t = BTreeMap::new();
let a: &[MessageItem] = try!(reply[0].inner());
for p in a.iter() {
let (k, v) = try!(p.inner());
let (k, v): (&String, &MessageItem) = (try!(k.inner()), try!(v.inner()));
t.insert(k.clone(), v.clone());
}
Ok(t)
})().map_err(|_| {
let f = format!("Invalid reply for property GetAll: '{:?}'", reply);
Error::new_custom("InvalidReply", &f)
})
}
}
pub struct PropHandler<'a> {
p: Props<'a>,
map: BTreeMap<String, MessageItem>,
}
impl<'a> PropHandler<'a> {
pub fn new(p: Props) -> PropHandler {
PropHandler { p: p, map: BTreeMap::new() }
}
pub fn get_all(&mut self) -> Result<(), Error> {
self.map = try!(self.p.get_all());
Ok(())
}
pub fn map_mut(&mut self) -> &mut BTreeMap<String, MessageItem> { &mut self.map }
pub fn map(&self) -> &BTreeMap<String, MessageItem> { &self.map }
pub fn get(&mut self, propname: &str) -> Result<&MessageItem, Error> {
let v = try!(self.p.get(propname));
self.map.insert(propname.to_string(), v);
Ok(self.map.get(propname).unwrap())
}
pub fn set(&mut self, propname: &str, value: MessageItem) -> Result<(), Error> {
try!(self.p.set(propname, value.clone()));
self.map.insert(propname.to_string(), value);
Ok(())
}
}
#[test]
fn test_get_policykit_version() {
use super::BusType;
let c = Connection::get_private(BusType::System).unwrap();
let p = Props::new(&c, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority", 10000);
let v = p.get("BackendVersion").unwrap();
let vall = p.get_all().unwrap();
let v2 = vall.get("BackendVersion").unwrap();
assert_eq!(&v, &*v2);
match v {
MessageItem::Str(ref s) => { println!("Policykit Backend version is {}", s); }
_ => { panic!("Invalid Get: {:?}", v); }
};
}