dbus_tree/
utils.rs

1// Small structs that don't have their own unit.
2
3use dbus::strings::{Signature, Member, Path, Interface as IfaceName};
4use std::collections::{BTreeMap, btree_map};
5use std::sync::Arc;
6
7pub type ArcMap<K, V> = BTreeMap<K, Arc<V>>;
8
9#[derive(Clone, Debug)]
10pub enum IterE<'a, V: 'a> {
11    Path(btree_map::Values<'a, Arc<Path<'static>>, Arc<V>>),
12    Iface(btree_map::Values<'a, Arc<IfaceName<'static>>, Arc<V>>),
13    Member(btree_map::Values<'a, Member<'static>, Arc<V>>),
14    String(btree_map::Values<'a, String, Arc<V>>),
15}
16
17#[derive(Clone, Debug)]
18/// Iterator struct, returned from iterator methods on Tree, Objectpath and Interface.
19pub struct Iter<'a, V: 'a>(IterE<'a, V>);
20
21impl<'a, V: 'a> From<IterE<'a, V>> for Iter<'a, V> { fn from(x: IterE<'a, V>) -> Iter<'a, V> { Iter(x) }}
22
23impl<'a, V: 'a> Iterator for Iter<'a, V> {
24    type Item = &'a Arc<V>;
25    fn next(&mut self) -> Option<Self::Item> {
26        match self.0 {
27            IterE::Path(ref mut x) => x.next(),
28            IterE::Iface(ref mut x) => x.next(),
29            IterE::Member(ref mut x) => x.next(),
30            IterE::String(ref mut x) => x.next(),
31        }
32    }
33}
34
35#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
36/// A D-Bus Argument.
37pub struct Argument(Option<String>, Signature<'static>);
38
39impl Argument {
40    /// Create a new Argument.
41    pub fn new(name: Option<String>, sig: Signature<'static>) -> Argument { Argument(name, sig) }
42
43    /// Descriptive name (if any).
44    pub fn name(&self) -> Option<&str> { self.0.as_ref().map(|s| &**s) }
45
46    /// Type signature of argument.
47    pub fn signature(&self) -> &Signature<'static> { &self.1 }
48
49    fn introspect(&self, indent: &str, dir: &str) -> String {
50        let n = self.0.as_ref().map(|n| format!("name=\"{}\" ", n)).unwrap_or_default();
51        format!("{}<arg {}type=\"{}\"{}/>\n", indent, n, self.1, dir)
52    }
53
54}
55
56pub fn introspect_args(args: &[Argument], indent: &str, dir: &str) -> String {
57    args.iter().fold("".to_string(), |aa, az| format!("{}{}", aa, az.introspect(indent, dir)))
58}
59
60// Small helper struct to reduce memory somewhat for objects without annotations
61#[derive(Clone, Debug, Default)]
62pub struct Annotations(Option<BTreeMap<String, String>>);
63
64impl Annotations {
65    pub fn new() -> Annotations { Annotations(None) }
66
67    pub fn insert<N: Into<String>, V: Into<String>>(&mut self, n: N, v: V) {
68       if self.0.is_none() { self.0 = Some(BTreeMap::new()) }
69        self.0.as_mut().unwrap().insert(n.into(), v.into());
70    }
71
72    pub fn introspect(&self, indent: &str) -> String {
73        self.0.as_ref().map(|s| s.iter().fold("".into(), |aa, (ak, av)| {
74            format!("{}{}<annotation name=\"{}\" value=\"{}\"/>\n", aa, indent, ak, av)
75        })).unwrap_or_default()
76    }
77}
78
79// Doesn't work, conflicting impls
80// impl<S: Into<Signature>> From<S> for Argument
81
82impl From<Signature<'static>> for Argument {
83    fn from(t: Signature<'static>) -> Argument { Argument(None, t) }
84}
85
86impl<'a> From<&'a str> for Argument {
87    fn from(t: &'a str) -> Argument { Argument(None, String::from(t).into()) }
88}
89
90impl<N: Into<String>, S: Into<Signature<'static>>> From<(N, S)> for Argument {
91    fn from((n, s): (N, S)) -> Argument { Argument(Some(n.into()), s.into()) }
92}
93
94pub trait Introspect {
95    // At some point we might want to switch to fmt::Write / fmt::Formatter for performance...
96    fn xml_name(&self) -> &'static str;
97    fn xml_params(&self) -> String;
98    fn xml_contents(&self) -> String;
99}