dbus_message_parser/value/
value_enum.rs

1use crate::value::{Array, ObjectPath, Struct, Type, TypeError};
2#[cfg(target_family = "unix")]
3use std::os::unix::io::RawFd;
4
5/// An enum representing a [DBus value].
6///
7/// [DBus value]: https://dbus.freedesktop.org/doc/dbus-specification.html#type-system
8#[derive(Debug, Clone, PartialOrd, PartialEq)]
9pub enum Value {
10    Byte(u8),
11    Boolean(bool),
12    Int16(i16),
13    Uint16(u16),
14    Int32(i32),
15    Uint32(u32),
16    Int64(i64),
17    Uint64(u64),
18    Double(f64),
19    String(String),
20    ObjectPath(ObjectPath),
21    Signature(Vec<Type>),
22    Array(Array),
23    Struct(Struct),
24    DictEntry(Box<(Value, Value)>),
25    Variant(Box<Value>),
26    #[cfg(target_family = "unix")]
27    UnixFD(RawFd),
28}
29
30impl Value {
31    /// Write the signature of the `Value` object into the `s` argument.
32    pub(crate) fn to_signature_string(
33        &self,
34        signature_string: &mut String,
35        array_depth: u8,
36        struct_depth: u8,
37        dict_depth: u8,
38    ) -> Result<(), TypeError> {
39        Type::check_depth(array_depth, struct_depth, dict_depth)?;
40        match self {
41            Value::Byte(_) => signature_string.push('y'),
42            Value::Boolean(_) => signature_string.push('b'),
43            Value::Int16(_) => signature_string.push('n'),
44            Value::Uint16(_) => signature_string.push('q'),
45            Value::Int32(_) => signature_string.push('i'),
46            Value::Uint32(_) => signature_string.push('u'),
47            Value::Int64(_) => signature_string.push('x'),
48            Value::Uint64(_) => signature_string.push('t'),
49            Value::Double(_) => signature_string.push('d'),
50            Value::String(_) => signature_string.push('s'),
51            Value::ObjectPath(_) => signature_string.push('o'),
52            Value::Signature(_) => signature_string.push('g'),
53            Value::Array(array) => {
54                signature_string.push('a');
55                array.get_type().try_to_string(
56                    signature_string,
57                    array_depth + 1,
58                    struct_depth,
59                    dict_depth,
60                )?;
61            }
62            Value::Struct(struct_) => {
63                signature_string.push('(');
64                for v in struct_.as_ref() {
65                    v.to_signature_string(
66                        signature_string,
67                        array_depth,
68                        struct_depth + 1,
69                        dict_depth,
70                    )?;
71                }
72                signature_string.push(')');
73            }
74            Value::DictEntry(b) => {
75                signature_string.push('{');
76                let (key, value) = &**b;
77                key.to_signature_string(
78                    signature_string,
79                    array_depth,
80                    struct_depth,
81                    dict_depth + 1,
82                )?;
83                value.to_signature_string(
84                    signature_string,
85                    array_depth,
86                    struct_depth,
87                    dict_depth + 1,
88                )?;
89                signature_string.push('}');
90            }
91            Value::Variant(_) => signature_string.push('v'),
92            #[cfg(target_family = "unix")]
93            Value::UnixFD(_) => signature_string.push('h'),
94        }
95        Type::check_len(signature_string)?;
96        Ok(())
97    }
98
99    fn from_value_to_type(
100        &self,
101        array_depth: u8,
102        struct_depth: u8,
103        dict_depth: u8,
104    ) -> Result<Type, TypeError> {
105        Type::check_depth(array_depth, struct_depth, dict_depth)?;
106        match self {
107            Value::Byte(_) => Ok(Type::Byte),
108            Value::Boolean(_) => Ok(Type::Boolean),
109            Value::Int16(_) => Ok(Type::Int16),
110            Value::Uint16(_) => Ok(Type::Uint16),
111            Value::Int32(_) => Ok(Type::Int32),
112            Value::Uint32(_) => Ok(Type::Uint32),
113            Value::Int64(_) => Ok(Type::Int64),
114            Value::Uint64(_) => Ok(Type::Uint64),
115            #[cfg(target_family = "unix")]
116            Value::UnixFD(_) => Ok(Type::UnixFD),
117            Value::Double(_) => Ok(Type::Double),
118            Value::String(_) => Ok(Type::String),
119            Value::ObjectPath(_) => Ok(Type::ObjectPath),
120            Value::Signature(_) => Ok(Type::Signature),
121            Value::Array(array) => {
122                let signature = Box::new(array.get_type().clone());
123                Ok(Type::Array(signature))
124            }
125            Value::Struct(struct_) => {
126                let mut signatures = Vec::new();
127                for value in struct_.as_ref() {
128                    let signature =
129                        value.from_value_to_type(array_depth, struct_depth + 1, dict_depth)?;
130                    signatures.push(signature);
131                }
132                Ok(Type::Struct(signatures))
133            }
134            Value::DictEntry(b) => {
135                let key_signature =
136                    b.0.from_value_to_type(array_depth, struct_depth, dict_depth + 1)?;
137                let value_signature =
138                    b.1.from_value_to_type(array_depth, struct_depth, dict_depth + 1)?;
139                let signature = Box::new((key_signature, value_signature));
140                Ok(Type::DictEntry(signature))
141            }
142            Value::Variant(_) => Ok(Type::Variant),
143        }
144    }
145
146    /// Returns the [`Type`] of the `Value`.
147    ///
148    /// [`Type`]: crate::value::Type
149    pub fn get_type(&self) -> Result<Type, TypeError> {
150        self.from_value_to_type(0, 0, 0)
151    }
152}