Skip to main content

dbus_serialize/
types.rs

1//! Contains the Value and BasicValue enums, as well as traits and helper types for them
2use std::collections::HashMap;
3
4/// BasicValue covers the "basic" D-Bus types, that is those that are allowed to be used as keys in
5/// a dictionary.
6#[derive(PartialEq,Eq,Debug,Hash,Clone)]
7pub enum BasicValue {
8    Byte(u8),
9    Boolean(bool),
10    Int16(i16),
11    Uint16(u16),
12    Int32(i32),
13    Uint32(u32),
14    Int64(i64),
15    Uint64(u64),
16    String(String),
17    ObjectPath(Path),
18    Signature(Signature),
19}
20
21#[derive(Clone,PartialEq,Eq,Debug,Hash)]
22pub struct Path(pub String);
23
24#[derive(Clone,PartialEq,Eq,Debug,Hash)]
25pub struct Signature(pub String);
26
27impl BasicValue {
28    /// Returns the D-Bus type signature that corresponds to the Value
29    pub fn get_signature(&self) -> &str {
30        match self {
31            &BasicValue::Byte(_) => "y",
32            &BasicValue::Boolean(_) => "b",
33            &BasicValue::Int16(_) => "n",
34            &BasicValue::Uint16(_) => "q",
35            &BasicValue::Int32(_) => "i",
36            &BasicValue::Uint32(_) => "u",
37            &BasicValue::Int64(_) => "x",
38            &BasicValue::Uint64(_) => "t",
39            &BasicValue::String(_) => "s",
40            &BasicValue::ObjectPath(_) => "o",
41            &BasicValue::Signature(_) => "g",
42        }
43    }
44}
45
46/// A Struct is an ordered sequence of Value objects, which may be of different varieties.
47/// signature must be of the form "(<type>)", where <type> is the signature of contents of
48/// objects.
49#[derive(PartialEq,Debug,Clone)]
50pub struct Struct {
51    pub objects: Vec<Value>,
52    pub signature: Signature
53}
54
55/// A Variant is a boxed type-erased value.  It is trasmitted on the wire with its signature.
56/// It is useful for arrays with varying types and for allowing DBus method argument types to be
57/// determined at runtime.  signature contains the signature of the boxed value.
58#[derive(PartialEq,Debug,Clone)]
59pub struct Variant {
60    pub object: Box<Value>,
61    pub signature: Signature
62}
63
64impl Variant {
65    /// Create a new variant to wrap the given value.  s must be the signature of v.
66    pub fn new (v: Value, s: &str) -> Variant {
67        Variant {
68            object: Box::new(v),
69            signature: Signature(s.to_string())
70        }
71    }
72}
73
74/// An Array is an ordered sequence of Value objects which must all be of the same variety.  That
75/// is, it is not value to have a Uint8 and a Uint32 as elements of the same Array.
76#[derive(Clone,Debug,PartialEq)]
77pub struct Array {
78    pub objects: Vec<Value>,
79    signature: Signature
80}
81
82impl Array {
83    /// Create a new array from the given vector of Value.  This function may only be used when it
84    /// is never possible for the input vector to be empty.  The reason is that it is impossible to
85    /// determine the type signature for an empty vector.  Use new_with_sig instead.
86    ///
87    /// # Panics
88    /// If objects.len() is 0, this function will panic.
89    pub fn new(objects: Vec<Value>) -> Array {
90        let inner_sig = objects.iter().next().unwrap().get_signature().to_string();
91        let sig = "a".to_string() + &inner_sig;
92        Array {
93            objects: objects,
94            signature: Signature(sig)
95        }
96    }
97
98    /// Create a new array from the given vector.  If sig is not of the form a<type>
99    /// or if objects is non-empty and the inner type does not match the type of the contents,
100    /// the resulting value will be invalid and will not encode correctly.
101    pub fn new_with_sig(objects: Vec<Value>, sig: String) -> Array {
102        Array {
103            objects: objects,
104            signature: Signature(sig)
105        }
106    }
107}
108
109#[derive(Clone,Debug,PartialEq)]
110pub struct Dictionary {
111    pub map: HashMap<BasicValue,Value>,
112    signature: Signature
113}
114
115impl Dictionary {
116    /// Create a new Dictionary from the given map.  This function may only be used when it
117    /// is never possible for the input map to be empty.  The reason is that it is impossible to
118    /// determine the type signature for an empty vector.  Use new_with_sig instead.
119    ///
120    /// # Panics
121    /// If map.len() is 0, this function will panic.
122    pub fn new(map: HashMap<BasicValue,Value>) -> Dictionary {
123        let key_type = map.keys().next().unwrap().get_signature().to_string();
124        let val_type = map.values().next().unwrap().get_signature().to_string();
125        let sig = "a{".to_string() + &key_type + &val_type + "}";
126        Dictionary {
127            map: map,
128            signature: Signature(sig)
129        }
130    }
131
132    /// Create a new Dictionary from the given map.  If sig is not of the form a{<type><type>}
133    /// or if map is non-empty and the inner types do not match the type of the map's contents,
134    /// the resulting value will be invalid and will not encode correctly.
135    pub fn new_with_sig(map: HashMap<BasicValue,Value>, sig: String) -> Dictionary {
136        Dictionary {
137            map: map,
138            signature: Signature(sig)
139        }
140    }
141}
142
143/// Root type for any D-Bus value
144#[derive(PartialEq,Debug,Clone)]
145pub enum Value {
146    BasicValue(BasicValue),
147    Double(f64),
148    Array(Array),
149    Variant(Variant),
150    Struct(Struct),
151    Dictionary(Dictionary)
152}
153
154impl Value {
155    /// Returns the D-Bus type signature that corresponds to the Value
156    pub fn get_signature(&self) -> &str {
157        match self {
158            &Value::BasicValue(ref x) => x.get_signature(),
159            &Value::Double(_) => "d",
160            &Value::Array(ref x) => &x.signature.0,
161            &Value::Variant(_) => "v",
162            &Value::Struct(ref x) => &x.signature.0,
163            &Value::Dictionary(ref x) => &x.signature.0
164        }
165    }
166}
167
168#[test]
169fn test_from () {
170    let x = Value::from(12);
171    assert_eq!(x, Value::BasicValue(BasicValue::Int32(12)));
172    let y = Value::from("foobar");
173    assert_eq!(y, Value::BasicValue(BasicValue::String("foobar".to_string())));
174}