1use crate::value::{
2 Bus, BusError, Error, ErrorError, Interface, InterfaceError, Member, MemberError, ObjectPath,
3 Struct, Type, Value,
4};
5use std::convert::TryFrom;
6use thiserror::Error as ThisError;
7
8macro_rules! try_set_field {
9 ($function:ident, $field:ident, $variant:ident, $multiple_error:ident, $error:ident $(,$convert:expr)?) => {
10 fn $function(&mut self, v: Value) -> Result<(), FieldsError> {
11 if self.$field.is_some() {
12 return Err(FieldsError::$multiple_error(v));
13 }
14
15 match v {
16 Value::$variant(o) => {
17 $(let o = $convert(o)?;)?
18 self.$field = Some(o);
19 Ok(())
20 }
21 v => Err(FieldsError::$error(v)),
22 }
23 }
24 };
25}
26
27macro_rules! add_to_vec {
28 ($vec:ident, $fields:ident, $field:ident, $number:literal, $variant:ident $(,$convert:ident)?) => {
29 if let Some(v) = $fields.$field {
30 $(let v = v.$convert();)?
31 $vec.push(Value::Struct(Struct(vec![
32 Value::Byte($number),
33 Value::Variant(Box::new(Value::$variant(v))),
34 ])));
35 }
36 };
37}
38
39#[derive(Debug, PartialEq, ThisError)]
40pub enum FieldsError {
41 #[error("Value is not a Struct: {0:?}")]
42 Struct(Value),
43 #[error("Struct does not contain exactly two values: {0}")]
44 Length(usize),
45 #[error("Second value is not a Variant: {0:?}")]
46 Variant(Value),
47 #[error("First value is not a Byte: {0:?}")]
48 Byte(Value),
49 #[error("Variant does not contain a ObjectPath: {0:?}")]
50 Path(Value),
51 #[error("Variant does not contain a String: {0:?}")]
52 Interface(Value),
53 #[error("String could not be converted to an Interface: {0}")]
54 InterfaceError(#[from] InterfaceError),
55 #[error("Variant does not contain a String: {0:?}")]
56 Member(Value),
57 #[error("String could not be converted to an Member: {0}")]
58 MemberError(#[from] MemberError),
59 #[error("Variant does not contain a String: {0:?}")]
60 ErrorName(Value),
61 #[error("String could not be converted to an ErrorName: {0}")]
62 ErrorError(#[from] ErrorError),
63 #[error("Variant does not contain a Uint32: {0:?}")]
64 ReplySerial(Value),
65 #[error("")]
66 BusError(#[from] BusError),
67 #[error("Variant does not contain a String: {0:?}")]
68 Destination(Value),
69 #[error("Variant does not contain a String: {0:?}")]
70 Sender(Value),
71 #[error("Variant does not contain a Signature: {0:?}")]
72 Signature(Value),
73 #[cfg(target_family = "unix")]
74 #[error("Variant does not contain a Uint32: {0:?}")]
75 UnixFDs(Value),
76 #[error("The byte does not has a valid number: {0}")]
77 InvalidNumber(u8),
78 #[error("The path is defined mutlple times: {0:?}")]
79 MultiplePath(Value),
80 #[error("The interface is defined mutlple times: {0:?}")]
81 MultipleInterface(Value),
82 #[error("The member is defined mutlple times: {0:?}")]
83 MultipleMember(Value),
84 #[error("The error name is defined mutlple times: {0:?}")]
85 MultipleErrorName(Value),
86 #[error("The reply serial is defined mutlple times: {0:?}")]
87 MultipleReplySerial(Value),
88 #[error("The destination is defined mutlple times: {0:?}")]
89 MultipleDestination(Value),
90 #[error("The destination is defined mutlple times: {0:?}")]
91 MultipleSender(Value),
92 #[error("The signature is defined mutlple times: {0:?}")]
93 MultipleSignature(Value),
94 #[cfg(target_family = "unix")]
95 #[error("The unix fds is defined mutlple times: {0:?}")]
96 MultipleUnixFDs(Value),
97}
98
99#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq, Default)]
103pub struct Fields {
104 pub path: Option<ObjectPath>,
105 pub interface: Option<Interface>,
106 pub member: Option<Member>,
107 pub error_name: Option<Error>,
108 pub reply_serial: Option<u32>,
109 pub destination: Option<Bus>,
110 pub sender: Option<Bus>,
111 pub signature: Option<Vec<Type>>,
112 #[cfg(target_family = "unix")]
113 pub unix_fds: Option<u32>,
114}
115
116impl Fields {
117 try_set_field!(try_set_path, path, ObjectPath, MultiplePath, Path);
118 try_set_field!(
119 try_set_interface,
120 interface,
121 String,
122 MultipleInterface,
123 Interface,
124 Interface::try_from
125 );
126 try_set_field!(
127 try_set_member,
128 member,
129 String,
130 MultipleMember,
131 Member,
132 Member::try_from
133 );
134 try_set_field!(
135 try_set_error_name,
136 error_name,
137 String,
138 MultipleErrorName,
139 ErrorName,
140 Error::try_from
141 );
142 try_set_field!(
143 try_set_reply_serial,
144 reply_serial,
145 Uint32,
146 MultipleReplySerial,
147 ReplySerial
148 );
149 try_set_field!(
150 try_set_destination,
151 destination,
152 String,
153 MultipleDestination,
154 Destination,
155 Bus::try_from
156 );
157 try_set_field!(
158 try_set_sender,
159 sender,
160 String,
161 MultipleSender,
162 Sender,
163 Bus::try_from
164 );
165 try_set_field!(
166 try_set_signature,
167 signature,
168 Signature,
169 MultipleSignature,
170 Signature
171 );
172 #[cfg(target_family = "unix")]
173 try_set_field!(try_set_unix_fds, unix_fds, Uint32, MultipleUnixFDs, UnixFDs);
174
175 fn try_set_field(&mut self, b: u8, v: Value) -> Result<(), FieldsError> {
176 match b {
177 1 => self.try_set_path(v),
178 2 => self.try_set_interface(v),
179 3 => self.try_set_member(v),
180 4 => self.try_set_error_name(v),
181 5 => self.try_set_reply_serial(v),
182 6 => self.try_set_destination(v),
183 7 => self.try_set_sender(v),
184 8 => self.try_set_signature(v),
185 #[cfg(target_family = "unix")]
186 9 => self.try_set_unix_fds(v),
187 b => Err(FieldsError::InvalidNumber(b)),
189 }
190 }
191}
192
193fn unwrap_value(value: Value) -> Result<(u8, Value), FieldsError> {
194 let mut values: Vec<Value> = match value {
196 Value::Struct(struct_) => struct_.into(),
197 v => return Err(FieldsError::Struct(v)),
198 };
199 let values_len = values.len();
201 if values_len != 2 {
202 return Err(FieldsError::Length(values_len));
203 }
204 let v = match values.pop().unwrap() {
206 Value::Variant(v) => *v,
207 v => return Err(FieldsError::Variant(v)),
208 };
209 let b = match values.pop().unwrap() {
211 Value::Byte(b) => b,
212 v => return Err(FieldsError::Byte(v)),
213 };
214
215 Ok((b, v))
216}
217
218impl TryFrom<Vec<Value>> for Fields {
219 type Error = FieldsError;
220
221 fn try_from(values: Vec<Value>) -> Result<Self, Self::Error> {
222 let mut fields = Fields::default();
223
224 for value in values {
225 let (b, v) = unwrap_value(value)?;
226 fields.try_set_field(b, v)?;
227 }
228
229 Ok(fields)
230 }
231}
232
233impl From<Fields> for Vec<Value> {
234 fn from(fields: Fields) -> Self {
235 let mut values = Vec::new();
236
237 add_to_vec!(values, fields, path, 1, ObjectPath);
238 add_to_vec!(values, fields, interface, 2, String, to_string);
239 add_to_vec!(values, fields, member, 3, String, to_string);
240 add_to_vec!(values, fields, error_name, 4, String, to_string);
241 add_to_vec!(values, fields, reply_serial, 5, Uint32);
242 add_to_vec!(values, fields, destination, 6, String, to_string);
243 add_to_vec!(values, fields, sender, 7, String, to_string);
244 add_to_vec!(values, fields, signature, 8, Signature);
245 #[cfg(target_family = "unix")]
246 add_to_vec!(values, fields, unix_fds, 9, Uint32);
247 values
248 }
249}