1 | use serde::de::{self, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Visitor}; |
2 | use static_assertions::assert_impl_all; |
3 | |
4 | use std::{marker::PhantomData, str}; |
5 | |
6 | #[cfg (unix)] |
7 | use std::os::fd::AsFd; |
8 | |
9 | use crate::{ |
10 | de::{DeserializerCommon, ValueParseStage}, |
11 | serialized::{Context, Format}, |
12 | signature_parser::SignatureParser, |
13 | utils::*, |
14 | Basic, Error, ObjectPath, Result, Signature, |
15 | }; |
16 | |
17 | #[cfg (unix)] |
18 | use crate::Fd; |
19 | |
20 | /// Our D-Bus deserialization implementation. |
21 | #[derive (Debug)] |
22 | pub(crate) struct Deserializer<'de, 'sig, 'f, F>(pub(crate) DeserializerCommon<'de, 'sig, 'f, F>); |
23 | |
24 | assert_impl_all!(Deserializer<'_, '_, '_, ()>: Send, Sync, Unpin); |
25 | |
26 | impl<'de, 'sig, 'f, F> Deserializer<'de, 'sig, 'f, F> { |
27 | /// Create a Deserializer struct instance. |
28 | /// |
29 | /// On Windows, there is no `fds` argument. |
30 | pub fn new<'r: 'de, S>( |
31 | bytes: &'r [u8], |
32 | #[cfg (unix)] fds: Option<&'f [F]>, |
33 | signature: S, |
34 | ctxt: Context, |
35 | ) -> Result<Self> |
36 | where |
37 | S: TryInto<Signature<'sig>>, |
38 | S::Error: Into<Error>, |
39 | { |
40 | assert_eq!(ctxt.format(), Format::DBus); |
41 | |
42 | let signature = signature.try_into().map_err(Into::into)?; |
43 | let sig_parser = SignatureParser::new(signature); |
44 | Ok(Self(DeserializerCommon { |
45 | ctxt, |
46 | sig_parser, |
47 | bytes, |
48 | #[cfg (unix)] |
49 | fds, |
50 | #[cfg (not(unix))] |
51 | fds: PhantomData, |
52 | pos: 0, |
53 | container_depths: Default::default(), |
54 | })) |
55 | } |
56 | } |
57 | |
58 | macro_rules! deserialize_basic { |
59 | ($method:ident $read_method:ident $visitor_method:ident($type:ty)) => { |
60 | fn $method<V>(self, visitor: V) -> Result<V::Value> |
61 | where |
62 | V: Visitor<'de>, |
63 | { |
64 | let v = self |
65 | .0 |
66 | .ctxt |
67 | .endian() |
68 | .$read_method(self.0.next_const_size_slice::<$type>()?); |
69 | |
70 | visitor.$visitor_method(v) |
71 | } |
72 | }; |
73 | } |
74 | |
75 | macro_rules! deserialize_as { |
76 | ($method:ident => $as:ident) => { |
77 | deserialize_as!($method() => $as()); |
78 | }; |
79 | ($method:ident($($in_arg:ident: $type:ty),*) => $as:ident($($as_arg:expr),*)) => { |
80 | #[inline] |
81 | fn $method<V>(self, $($in_arg: $type,)* visitor: V) -> Result<V::Value> |
82 | where |
83 | V: Visitor<'de>, |
84 | { |
85 | self.$as($($as_arg,)* visitor) |
86 | } |
87 | } |
88 | } |
89 | |
90 | impl<'de, 'd, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> de::Deserializer<'de> |
91 | for &'d mut Deserializer<'de, 'sig, 'f, F> |
92 | { |
93 | type Error = Error; |
94 | |
95 | fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> |
96 | where |
97 | V: Visitor<'de>, |
98 | { |
99 | let c = self.0.sig_parser.next_char()?; |
100 | |
101 | crate::de::deserialize_any::<Self, V>(self, c, visitor) |
102 | } |
103 | |
104 | fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> |
105 | where |
106 | V: Visitor<'de>, |
107 | { |
108 | let v = self |
109 | .0 |
110 | .ctxt |
111 | .endian() |
112 | .read_u32(self.0.next_const_size_slice::<bool>()?); |
113 | let b = match v { |
114 | 1 => true, |
115 | 0 => false, |
116 | // As per D-Bus spec, only 0 and 1 values are allowed |
117 | _ => { |
118 | return Err(de::Error::invalid_value( |
119 | de::Unexpected::Unsigned(v as u64), |
120 | &"0 or 1" , |
121 | )) |
122 | } |
123 | }; |
124 | |
125 | visitor.visit_bool(b) |
126 | } |
127 | |
128 | fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> |
129 | where |
130 | V: Visitor<'de>, |
131 | { |
132 | self.deserialize_i16(visitor) |
133 | } |
134 | |
135 | deserialize_basic!(deserialize_i16 read_i16 visit_i16(i16)); |
136 | deserialize_basic!(deserialize_i64 read_i64 visit_i64(i64)); |
137 | deserialize_basic!(deserialize_u16 read_u16 visit_u16(u16)); |
138 | deserialize_basic!(deserialize_u32 read_u32 visit_u32(u32)); |
139 | deserialize_basic!(deserialize_u64 read_u64 visit_u64(u64)); |
140 | deserialize_basic!(deserialize_f64 read_f64 visit_f64(f64)); |
141 | |
142 | fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> |
143 | where |
144 | V: Visitor<'de>, |
145 | { |
146 | let bytes = deserialize_ay(self)?; |
147 | visitor.visit_byte_buf(bytes.into()) |
148 | } |
149 | |
150 | fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> |
151 | where |
152 | V: Visitor<'de>, |
153 | { |
154 | let bytes = deserialize_ay(self)?; |
155 | visitor.visit_borrowed_bytes(bytes) |
156 | } |
157 | |
158 | deserialize_as!(deserialize_char => deserialize_str); |
159 | deserialize_as!(deserialize_string => deserialize_str); |
160 | deserialize_as!(deserialize_tuple(_l: usize) => deserialize_struct("" , &[])); |
161 | deserialize_as!(deserialize_tuple_struct(n: &'static str, _l: usize) => deserialize_struct(n, &[])); |
162 | deserialize_as!(deserialize_struct(_n: &'static str, _f: &'static [&'static str]) => deserialize_seq()); |
163 | deserialize_as!(deserialize_map => deserialize_seq); |
164 | deserialize_as!(deserialize_ignored_any => deserialize_any); |
165 | |
166 | fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> |
167 | where |
168 | V: Visitor<'de>, |
169 | { |
170 | let v = match self.0.sig_parser.next_char()? { |
171 | #[cfg (unix)] |
172 | Fd::SIGNATURE_CHAR => { |
173 | self.0.sig_parser.skip_char()?; |
174 | let alignment = u32::alignment(Format::DBus); |
175 | self.0.parse_padding(alignment)?; |
176 | let idx = self.0.ctxt.endian().read_u32(self.0.next_slice(alignment)?); |
177 | self.0.get_fd(idx)? |
178 | } |
179 | _ => self |
180 | .0 |
181 | .ctxt |
182 | .endian() |
183 | .read_i32(self.0.next_const_size_slice::<i32>()?), |
184 | }; |
185 | |
186 | visitor.visit_i32(v) |
187 | } |
188 | |
189 | fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> |
190 | where |
191 | V: Visitor<'de>, |
192 | { |
193 | // Endianness is irrelevant for single bytes. |
194 | visitor.visit_u8(self.0.next_const_size_slice::<u8>().map(|bytes| bytes[0])?) |
195 | } |
196 | |
197 | fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> |
198 | where |
199 | V: Visitor<'de>, |
200 | { |
201 | let v = self |
202 | .0 |
203 | .ctxt |
204 | .endian() |
205 | .read_f64(self.0.next_const_size_slice::<f64>()?); |
206 | |
207 | visitor.visit_f32(f64_to_f32(v)) |
208 | } |
209 | |
210 | fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> |
211 | where |
212 | V: Visitor<'de>, |
213 | { |
214 | let len = match self.0.sig_parser.next_char()? { |
215 | Signature::SIGNATURE_CHAR | VARIANT_SIGNATURE_CHAR => { |
216 | let len_slice = self.0.next_slice(1)?; |
217 | |
218 | len_slice[0] as usize |
219 | } |
220 | <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR => { |
221 | let alignment = u32::alignment(Format::DBus); |
222 | self.0.parse_padding(alignment)?; |
223 | let len_slice = self.0.next_slice(alignment)?; |
224 | |
225 | self.0.ctxt.endian().read_u32(len_slice) as usize |
226 | } |
227 | c => { |
228 | let expected = format!( |
229 | "` {}`, ` {}`, ` {}` or ` {}`" , |
230 | <&str>::SIGNATURE_STR, |
231 | Signature::SIGNATURE_STR, |
232 | ObjectPath::SIGNATURE_STR, |
233 | VARIANT_SIGNATURE_CHAR, |
234 | ); |
235 | return Err(de::Error::invalid_type( |
236 | de::Unexpected::Char(c), |
237 | &expected.as_str(), |
238 | )); |
239 | } |
240 | }; |
241 | let slice = self.0.next_slice(len)?; |
242 | if slice.contains(&0) { |
243 | return Err(serde::de::Error::invalid_value( |
244 | serde::de::Unexpected::Char(' \0' ), |
245 | &"D-Bus string type must not contain interior null bytes" , |
246 | )); |
247 | } |
248 | self.0.pos += 1; // skip trailing null byte |
249 | let s = str::from_utf8(slice).map_err(Error::Utf8)?; |
250 | self.0.sig_parser.skip_char()?; |
251 | |
252 | visitor.visit_borrowed_str(s) |
253 | } |
254 | |
255 | fn deserialize_option<V>(self, #[allow (unused)] visitor: V) -> Result<V::Value> |
256 | where |
257 | V: Visitor<'de>, |
258 | { |
259 | #[cfg (feature = "option-as-array" )] |
260 | { |
261 | let c = self.0.sig_parser.next_char()?; |
262 | if c != ARRAY_SIGNATURE_CHAR { |
263 | return Err(de::Error::invalid_type( |
264 | de::Unexpected::Char(c), |
265 | &ARRAY_SIGNATURE_STR, |
266 | )); |
267 | } |
268 | self.0.sig_parser.skip_char()?; |
269 | // This takes care of parsing all the padding and getting the byte length. |
270 | let len = ArrayDeserializer::new(self)?.len; |
271 | if len == 0 { |
272 | self.0.sig_parser.parse_next_signature()?; |
273 | |
274 | visitor.visit_none() |
275 | } else { |
276 | visitor.visit_some(self) |
277 | } |
278 | } |
279 | |
280 | #[cfg (not(feature = "option-as-array" ))] |
281 | Err(de::Error::custom( |
282 | "Can only decode Option<T> from D-Bus format if `option-as-array` feature is enabled" , |
283 | )) |
284 | } |
285 | |
286 | fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> |
287 | where |
288 | V: Visitor<'de>, |
289 | { |
290 | visitor.visit_unit() |
291 | } |
292 | |
293 | fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> |
294 | where |
295 | V: Visitor<'de>, |
296 | { |
297 | visitor.visit_unit() |
298 | } |
299 | |
300 | fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> |
301 | where |
302 | V: Visitor<'de>, |
303 | { |
304 | visitor.visit_newtype_struct(self) |
305 | } |
306 | |
307 | fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> |
308 | where |
309 | V: Visitor<'de>, |
310 | { |
311 | match self.0.sig_parser.next_char()? { |
312 | VARIANT_SIGNATURE_CHAR => { |
313 | let value_de = ValueDeserializer::new(self); |
314 | |
315 | visitor.visit_seq(value_de) |
316 | } |
317 | ARRAY_SIGNATURE_CHAR => { |
318 | self.0.sig_parser.skip_char()?; |
319 | let next_signature_char = self.0.sig_parser.next_char()?; |
320 | let array_de = ArrayDeserializer::new(self)?; |
321 | |
322 | if next_signature_char == DICT_ENTRY_SIG_START_CHAR { |
323 | visitor.visit_map(ArrayMapDeserializer(array_de)) |
324 | } else { |
325 | visitor.visit_seq(ArraySeqDeserializer(array_de)) |
326 | } |
327 | } |
328 | STRUCT_SIG_START_CHAR => { |
329 | let signature = self.0.sig_parser.next_signature()?; |
330 | let alignment = alignment_for_signature(&signature, Format::DBus)?; |
331 | self.0.parse_padding(alignment)?; |
332 | |
333 | self.0.sig_parser.skip_char()?; |
334 | |
335 | self.0.container_depths = self.0.container_depths.inc_structure()?; |
336 | let v = visitor.visit_seq(StructureDeserializer { de: self }); |
337 | self.0.container_depths = self.0.container_depths.dec_structure(); |
338 | |
339 | v |
340 | } |
341 | u8::SIGNATURE_CHAR => { |
342 | // Empty struct: encoded as a `0u8`. |
343 | let _: u8 = serde::Deserialize::deserialize(&mut *self)?; |
344 | |
345 | visitor.visit_seq(StructureDeserializer { de: self }) |
346 | } |
347 | c => Err(de::Error::invalid_type( |
348 | de::Unexpected::Char(c), |
349 | &format!( |
350 | "` {VARIANT_SIGNATURE_CHAR}`, ` {ARRAY_SIGNATURE_CHAR}` or ` {STRUCT_SIG_START_CHAR}`" , |
351 | ) |
352 | .as_str(), |
353 | )), |
354 | } |
355 | } |
356 | |
357 | fn deserialize_enum<V>( |
358 | self, |
359 | name: &'static str, |
360 | _variants: &'static [&'static str], |
361 | visitor: V, |
362 | ) -> Result<V::Value> |
363 | where |
364 | V: Visitor<'de>, |
365 | { |
366 | let signature = self.0.sig_parser.next_signature()?; |
367 | let alignment = alignment_for_signature(&signature, self.0.ctxt.format())?; |
368 | self.0.parse_padding(alignment)?; |
369 | |
370 | let non_unit = if self.0.sig_parser.next_char()? == STRUCT_SIG_START_CHAR { |
371 | // This means we've a non-unit enum. Let's skip the `(`. |
372 | self.0.sig_parser.skip_char()?; |
373 | |
374 | true |
375 | } else { |
376 | false |
377 | }; |
378 | |
379 | let v = visitor.visit_enum(crate::de::Enum { |
380 | de: &mut *self, |
381 | name, |
382 | _phantom: PhantomData, |
383 | })?; |
384 | |
385 | if non_unit { |
386 | // For non-unit enum, we need to skip the closing paren. |
387 | self.0.sig_parser.skip_char()?; |
388 | } |
389 | |
390 | Ok(v) |
391 | } |
392 | |
393 | fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> |
394 | where |
395 | V: Visitor<'de>, |
396 | { |
397 | if self.0.sig_parser.next_char()? == <&str>::SIGNATURE_CHAR { |
398 | self.deserialize_str(visitor) |
399 | } else { |
400 | self.deserialize_u32(visitor) |
401 | } |
402 | } |
403 | |
404 | fn is_human_readable(&self) -> bool { |
405 | false |
406 | } |
407 | } |
408 | |
409 | struct ArrayDeserializer<'d, 'de, 'sig, 'f, F> { |
410 | de: &'d mut Deserializer<'de, 'sig, 'f, F>, |
411 | len: usize, |
412 | start: usize, |
413 | // alignment of element |
414 | element_alignment: usize, |
415 | // where value signature starts |
416 | element_signature_len: usize, |
417 | } |
418 | |
419 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> |
420 | ArrayDeserializer<'d, 'de, 'sig, 'f, F> |
421 | { |
422 | fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> { |
423 | de.0.parse_padding(ARRAY_ALIGNMENT_DBUS)?; |
424 | de.0.container_depths = de.0.container_depths.inc_array()?; |
425 | |
426 | let len = de.0.ctxt.endian().read_u32(de.0.next_slice(4)?) as usize; |
427 | let element_signature = de.0.sig_parser.next_signature()?; |
428 | let element_alignment = alignment_for_signature(&element_signature, Format::DBus)?; |
429 | let mut element_signature_len = element_signature.len(); |
430 | |
431 | // D-Bus requires padding for the first element even when there is no first element |
432 | // (i-e empty array) so we parse padding already. |
433 | de.0.parse_padding(element_alignment)?; |
434 | let start = de.0.pos; |
435 | |
436 | if de.0.sig_parser.next_char()? == DICT_ENTRY_SIG_START_CHAR { |
437 | de.0.sig_parser.skip_char()?; |
438 | element_signature_len -= 1; |
439 | } |
440 | |
441 | Ok(Self { |
442 | de, |
443 | len, |
444 | start, |
445 | element_alignment, |
446 | element_signature_len, |
447 | }) |
448 | } |
449 | |
450 | fn next<T>(&mut self, seed: T, sig_parser: SignatureParser<'_>) -> Result<T::Value> |
451 | where |
452 | T: DeserializeSeed<'de>, |
453 | { |
454 | let ctxt = Context::new_dbus( |
455 | self.de.0.ctxt.endian(), |
456 | self.de.0.ctxt.position() + self.de.0.pos, |
457 | ); |
458 | |
459 | let mut de = Deserializer::<F>(DeserializerCommon { |
460 | ctxt, |
461 | sig_parser, |
462 | bytes: subslice(self.de.0.bytes, self.de.0.pos..)?, |
463 | fds: self.de.0.fds, |
464 | pos: 0, |
465 | container_depths: self.de.0.container_depths, |
466 | }); |
467 | let v = seed.deserialize(&mut de); |
468 | self.de.0.pos += de.0.pos; |
469 | // No need for retaking the container depths as the child can't be incomplete. |
470 | |
471 | if self.de.0.pos > self.start + self.len { |
472 | return Err(serde::de::Error::invalid_length( |
473 | self.len, |
474 | &format!(">= {}" , self.de.0.pos - self.start).as_str(), |
475 | )); |
476 | } |
477 | |
478 | v |
479 | } |
480 | |
481 | fn next_element<T>( |
482 | &mut self, |
483 | seed: T, |
484 | sig_parser: SignatureParser<'_>, |
485 | ) -> Result<Option<T::Value>> |
486 | where |
487 | T: DeserializeSeed<'de>, |
488 | { |
489 | if self.done() { |
490 | self.de |
491 | .0 |
492 | .sig_parser |
493 | .skip_chars(self.element_signature_len)?; |
494 | self.de.0.container_depths = self.de.0.container_depths.dec_array(); |
495 | |
496 | return Ok(None); |
497 | } |
498 | |
499 | self.de.0.parse_padding(self.element_alignment)?; |
500 | |
501 | self.next(seed, sig_parser).map(Some) |
502 | } |
503 | |
504 | fn done(&self) -> bool { |
505 | self.de.0.pos == self.start + self.len |
506 | } |
507 | } |
508 | |
509 | fn deserialize_ay<'de, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F>( |
510 | de: &mut Deserializer<'de, '_, '_, F>, |
511 | ) -> Result<&'de [u8]> { |
512 | if de.0.sig_parser.next_signature()? != "ay" { |
513 | return Err(de::Error::invalid_type(unexp:de::Unexpected::Seq, &"ay" )); |
514 | } |
515 | |
516 | de.0.sig_parser.skip_char()?; |
517 | let ad: ArrayDeserializer<'_, '_, '_, '_, …> = ArrayDeserializer::new(de)?; |
518 | let len: usize = ad.len; |
519 | de.0.sig_parser.skip_char()?; |
520 | de.0.next_slice(len) |
521 | } |
522 | |
523 | struct ArraySeqDeserializer<'d, 'de, 'sig, 'f, F>(ArrayDeserializer<'d, 'de, 'sig, 'f, F>); |
524 | |
525 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> SeqAccess<'de> |
526 | for ArraySeqDeserializer<'d, 'de, 'sig, 'f, F> |
527 | { |
528 | type Error = Error; |
529 | |
530 | fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> |
531 | where |
532 | T: DeserializeSeed<'de>, |
533 | { |
534 | let sig_parser: SignatureParser<'sig> = self.0.de.0.sig_parser.clone(); |
535 | self.0.next_element(seed, sig_parser) |
536 | } |
537 | } |
538 | |
539 | struct ArrayMapDeserializer<'d, 'de, 'sig, 'f, F>(ArrayDeserializer<'d, 'de, 'sig, 'f, F>); |
540 | |
541 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> MapAccess<'de> |
542 | for ArrayMapDeserializer<'d, 'de, 'sig, 'f, F> |
543 | { |
544 | type Error = Error; |
545 | |
546 | fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>> |
547 | where |
548 | K: DeserializeSeed<'de>, |
549 | { |
550 | let sig_parser: SignatureParser<'sig> = self.0.de.0.sig_parser.clone(); |
551 | self.0.next_element(seed, sig_parser) |
552 | } |
553 | |
554 | fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> |
555 | where |
556 | V: DeserializeSeed<'de>, |
557 | { |
558 | let mut sig_parser: SignatureParser<'sig> = self.0.de.0.sig_parser.clone(); |
559 | // Skip key signature (always 1 char) |
560 | sig_parser.skip_char()?; |
561 | self.0.next(seed, sig_parser) |
562 | } |
563 | } |
564 | |
565 | #[derive (Debug)] |
566 | struct StructureDeserializer<'d, 'de, 'sig, 'f, F> { |
567 | de: &'d mut Deserializer<'de, 'sig, 'f, F>, |
568 | } |
569 | |
570 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> SeqAccess<'de> |
571 | for StructureDeserializer<'d, 'de, 'sig, 'f, F> |
572 | { |
573 | type Error = Error; |
574 | |
575 | fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> |
576 | where |
577 | T: DeserializeSeed<'de>, |
578 | { |
579 | let v: Result = seed.deserialize(&mut *self.de).map(op:Some); |
580 | |
581 | if self.de.0.sig_parser.next_char()? == STRUCT_SIG_END_CHAR { |
582 | // Last item in the struct |
583 | self.de.0.sig_parser.skip_char()?; |
584 | } |
585 | |
586 | v |
587 | } |
588 | } |
589 | |
590 | #[derive (Debug)] |
591 | struct ValueDeserializer<'d, 'de, 'sig, 'f, F> { |
592 | de: &'d mut Deserializer<'de, 'sig, 'f, F>, |
593 | stage: ValueParseStage, |
594 | sig_start: usize, |
595 | } |
596 | |
597 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> |
598 | ValueDeserializer<'d, 'de, 'sig, 'f, F> |
599 | { |
600 | fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Self { |
601 | let sig_start: usize = de.0.pos; |
602 | ValueDeserializer::<F> { |
603 | de, |
604 | stage: ValueParseStage::Signature, |
605 | sig_start, |
606 | } |
607 | } |
608 | } |
609 | |
610 | impl<'d, 'de, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> SeqAccess<'de> |
611 | for ValueDeserializer<'d, 'de, 'sig, 'f, F> |
612 | { |
613 | type Error = Error; |
614 | |
615 | fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> |
616 | where |
617 | T: DeserializeSeed<'de>, |
618 | { |
619 | match self.stage { |
620 | ValueParseStage::Signature => { |
621 | self.stage = ValueParseStage::Value; |
622 | |
623 | seed.deserialize(&mut *self.de).map(Some) |
624 | } |
625 | ValueParseStage::Value => { |
626 | self.stage = ValueParseStage::Done; |
627 | |
628 | let sig_len = self.de.0.bytes[self.sig_start] as usize; |
629 | // skip length byte |
630 | let sig_start = self.sig_start + 1; |
631 | let sig_end = sig_start + sig_len; |
632 | // Skip trailing nul byte |
633 | let value_start = sig_end + 1; |
634 | |
635 | let slice = subslice(self.de.0.bytes, sig_start..sig_end)?; |
636 | let signature = Signature::try_from(slice)?; |
637 | let sig_parser = SignatureParser::new(signature); |
638 | |
639 | let ctxt = Context::new( |
640 | Format::DBus, |
641 | self.de.0.ctxt.endian(), |
642 | self.de.0.ctxt.position() + value_start, |
643 | ); |
644 | let mut de = Deserializer::<F>(DeserializerCommon { |
645 | ctxt, |
646 | sig_parser, |
647 | bytes: subslice(self.de.0.bytes, value_start..)?, |
648 | fds: self.de.0.fds, |
649 | pos: 0, |
650 | container_depths: self.de.0.container_depths.inc_variant()?, |
651 | }); |
652 | |
653 | let v = seed.deserialize(&mut de).map(Some); |
654 | self.de.0.pos += de.0.pos; |
655 | |
656 | v |
657 | } |
658 | ValueParseStage::Done => Ok(None), |
659 | } |
660 | } |
661 | } |
662 | |
663 | impl<'de, 'd, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> EnumAccess<'de> |
664 | for crate::de::Enum<&'d mut Deserializer<'de, 'sig, 'f, F>, F> |
665 | { |
666 | type Error = Error; |
667 | type Variant = Self; |
668 | |
669 | fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)> |
670 | where |
671 | V: DeserializeSeed<'de>, |
672 | { |
673 | seed.deserialize(&mut *self.de).map(|v: >::Value| (v, self)) |
674 | } |
675 | } |
676 | |