1 | use serde::{ |
2 | de::{self, DeserializeSeed, VariantAccess, Visitor}, |
3 | Deserialize, |
4 | }; |
5 | use static_assertions::assert_impl_all; |
6 | |
7 | use std::{marker::PhantomData, str}; |
8 | |
9 | #[cfg (unix)] |
10 | use std::os::unix::io::RawFd; |
11 | |
12 | #[cfg (feature = "gvariant" )] |
13 | use crate::gvariant::Deserializer as GVDeserializer; |
14 | use crate::{ |
15 | container_depths::ContainerDepths, dbus::Deserializer as DBusDeserializer, |
16 | signature_parser::SignatureParser, utils::*, Basic, DynamicDeserialize, DynamicType, |
17 | EncodingContext, EncodingFormat, Error, ObjectPath, Result, Signature, Type, |
18 | }; |
19 | |
20 | #[cfg (unix)] |
21 | use crate::Fd; |
22 | |
23 | /// Deserialize `T` from a given slice of bytes, containing file descriptor indices. |
24 | /// |
25 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
26 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
27 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
28 | /// |
29 | /// This function is not available on Windows. |
30 | /// |
31 | /// # Examples |
32 | /// |
33 | /// ``` |
34 | /// use zvariant::{to_bytes_fds, from_slice_fds}; |
35 | /// use zvariant::{EncodingContext, Fd}; |
36 | /// |
37 | /// let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0); |
38 | /// let (encoded, fds) = to_bytes_fds(ctxt, &Fd::from(42)).unwrap(); |
39 | /// let decoded: Fd = from_slice_fds(&encoded, Some(&fds), ctxt).unwrap(); |
40 | /// assert_eq!(decoded, Fd::from(42)); |
41 | /// ``` |
42 | /// |
43 | /// [`from_slice`]: fn.from_slice.html |
44 | #[cfg (unix)] |
45 | pub fn from_slice_fds<'d, 'r: 'd, B, T: ?Sized>( |
46 | bytes: &'r [u8], |
47 | fds: Option<&[RawFd]>, |
48 | ctxt: EncodingContext<B>, |
49 | ) -> Result<T> |
50 | where |
51 | B: byteorder::ByteOrder, |
52 | T: Deserialize<'d> + Type, |
53 | { |
54 | let signature: Signature<'_> = T::signature(); |
55 | from_slice_fds_for_signature(bytes, fds, ctxt, &signature) |
56 | } |
57 | |
58 | /// Deserialize `T` from a given slice of bytes. |
59 | /// |
60 | /// If `T` is an, or (potentially) contains an [`Fd`], use [`from_slice_fds`] instead. |
61 | /// |
62 | /// # Examples |
63 | /// |
64 | /// ``` |
65 | /// use zvariant::{to_bytes, from_slice}; |
66 | /// use zvariant::EncodingContext; |
67 | /// |
68 | /// let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0); |
69 | /// let encoded = to_bytes(ctxt, "hello world" ).unwrap(); |
70 | /// let decoded: &str = from_slice(&encoded, ctxt).unwrap(); |
71 | /// assert_eq!(decoded, "hello world" ); |
72 | /// ``` |
73 | /// |
74 | /// [`Fd`]: struct.Fd.html |
75 | /// [`from_slice_fds`]: fn.from_slice_fds.html |
76 | pub fn from_slice<'d, 'r: 'd, B, T: ?Sized>(bytes: &'r [u8], ctxt: EncodingContext<B>) -> Result<T> |
77 | where |
78 | B: byteorder::ByteOrder, |
79 | T: Deserialize<'d> + Type, |
80 | { |
81 | let signature: Signature<'_> = T::signature(); |
82 | from_slice_for_signature(bytes, ctxt, &signature) |
83 | } |
84 | |
85 | /// Deserialize `T` from a given slice of bytes with the given signature. |
86 | /// |
87 | /// Use this function instead of [`from_slice`] if the value being deserialized does not implement |
88 | /// [`Type`]. Also, if `T` is an, or (potentially) contains an [`Fd`], use |
89 | /// [`from_slice_fds_for_signature`] instead. |
90 | /// |
91 | /// # Examples |
92 | /// |
93 | /// While `Type` derive supports enums, for this example, let's supposed it doesn't and we don't |
94 | /// want to manually implement `Type` trait either: |
95 | /// |
96 | /// ``` |
97 | /// use std::convert::TryInto; |
98 | /// use serde::{Deserialize, Serialize}; |
99 | /// |
100 | /// use zvariant::{to_bytes_for_signature, from_slice_for_signature}; |
101 | /// use zvariant::EncodingContext; |
102 | /// |
103 | /// let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0); |
104 | /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] |
105 | /// enum Unit { |
106 | /// Variant1, |
107 | /// Variant2, |
108 | /// Variant3, |
109 | /// } |
110 | /// |
111 | /// let signature = "u" .try_into().unwrap(); |
112 | /// let encoded = to_bytes_for_signature(ctxt, &signature, &Unit::Variant2).unwrap(); |
113 | /// assert_eq!(encoded.len(), 4); |
114 | /// let decoded: Unit = from_slice_for_signature(&encoded, ctxt, &signature).unwrap(); |
115 | /// assert_eq!(decoded, Unit::Variant2); |
116 | /// |
117 | /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] |
118 | /// enum NewType<'s> { |
119 | /// Variant1(&'s str), |
120 | /// Variant2(&'s str), |
121 | /// Variant3(&'s str), |
122 | /// } |
123 | /// |
124 | /// let signature = "(us)" .try_into().unwrap(); |
125 | /// let encoded = |
126 | /// to_bytes_for_signature(ctxt, &signature, &NewType::Variant2("hello" )).unwrap(); |
127 | /// assert_eq!(encoded.len(), 14); |
128 | /// let decoded: NewType<'_> = from_slice_for_signature(&encoded, ctxt, &signature).unwrap(); |
129 | /// assert_eq!(decoded, NewType::Variant2("hello" )); |
130 | /// |
131 | /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] |
132 | /// enum Structs { |
133 | /// Tuple(u8, u64), |
134 | /// Struct { y: u8, t: u64 }, |
135 | /// } |
136 | /// |
137 | /// // TODO: Provide convenience API to create complex signatures |
138 | /// let signature = "(u(yt))" .try_into().unwrap(); |
139 | /// let encoded = to_bytes_for_signature(ctxt, &signature, &Structs::Tuple(42, 42)).unwrap(); |
140 | /// assert_eq!(encoded.len(), 24); |
141 | /// let decoded: Structs = from_slice_for_signature(&encoded, ctxt, &signature).unwrap(); |
142 | /// assert_eq!(decoded, Structs::Tuple(42, 42)); |
143 | /// |
144 | /// let s = Structs::Struct { y: 42, t: 42 }; |
145 | /// let encoded = to_bytes_for_signature(ctxt, &signature, &s).unwrap(); |
146 | /// assert_eq!(encoded.len(), 24); |
147 | /// let decoded: Structs = from_slice_for_signature(&encoded, ctxt, &signature).unwrap(); |
148 | /// assert_eq!(decoded, Structs::Struct { y: 42, t: 42 }); |
149 | /// ``` |
150 | /// |
151 | /// [`Type`]: trait.Type.html |
152 | /// [`Fd`]: struct.Fd.html |
153 | /// [`from_slice_fds_for_signature`]: fn.from_slice_fds_for_signature.html |
154 | // TODO: Return number of bytes parsed? |
155 | pub fn from_slice_for_signature<'d, 'r: 'd, B, T: ?Sized>( |
156 | bytes: &'r [u8], |
157 | ctxt: EncodingContext<B>, |
158 | signature: &Signature<'_>, |
159 | ) -> Result<T> |
160 | where |
161 | B: byteorder::ByteOrder, |
162 | T: Deserialize<'d>, |
163 | { |
164 | _from_slice_fds_for_signature( |
165 | bytes, |
166 | #[cfg (unix)] |
167 | None, |
168 | ctxt, |
169 | signature, |
170 | ) |
171 | } |
172 | |
173 | /// Deserialize `T` from a given slice of bytes containing file descriptor indices, with the given |
174 | /// signature. |
175 | /// |
176 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
177 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
178 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
179 | /// |
180 | /// This function is not available on Windows. |
181 | /// |
182 | /// [`from_slice`]: fn.from_slice.html |
183 | /// [`from_slice_for_signature`]: fn.from_slice_for_signature.html |
184 | // TODO: Return number of bytes parsed? |
185 | #[cfg (unix)] |
186 | pub fn from_slice_fds_for_signature<'d, 'r: 'd, B, T: ?Sized>( |
187 | bytes: &'r [u8], |
188 | fds: Option<&[RawFd]>, |
189 | ctxt: EncodingContext<B>, |
190 | signature: &Signature<'_>, |
191 | ) -> Result<T> |
192 | where |
193 | B: byteorder::ByteOrder, |
194 | T: Deserialize<'d>, |
195 | { |
196 | _from_slice_fds_for_signature(bytes, fds, ctxt, signature) |
197 | } |
198 | |
199 | fn _from_slice_fds_for_signature<'d, 'r: 'd, B, T: ?Sized>( |
200 | bytes: &'r [u8], |
201 | #[cfg (unix)] fds: Option<&[RawFd]>, |
202 | ctxt: EncodingContext<B>, |
203 | signature: &Signature<'_>, |
204 | ) -> Result<T> |
205 | where |
206 | B: byteorder::ByteOrder, |
207 | T: Deserialize<'d>, |
208 | { |
209 | let mut de: Deserializer<'_, '_, '_, …> = match ctxt.format() { |
210 | #[cfg (feature = "gvariant" )] |
211 | EncodingFormat::GVariant => Deserializer::GVariant(GVDeserializer::new( |
212 | bytes, |
213 | #[cfg (unix)] |
214 | fds, |
215 | signature, |
216 | ctxt, |
217 | )), |
218 | EncodingFormat::DBus => Deserializer::DBus(DBusDeserializer::new( |
219 | bytes, |
220 | #[cfg (unix)] |
221 | fds, |
222 | signature, |
223 | ctxt, |
224 | )), |
225 | }; |
226 | |
227 | T::deserialize(&mut de) |
228 | } |
229 | |
230 | /// Deserialize `T` from a given slice of bytes containing file descriptor indices, with the given |
231 | /// signature. |
232 | /// |
233 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
234 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
235 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
236 | pub fn from_slice_for_dynamic_signature<'d, B, T>( |
237 | bytes: &'d [u8], |
238 | ctxt: EncodingContext<B>, |
239 | signature: &Signature<'d>, |
240 | ) -> Result<T> |
241 | where |
242 | B: byteorder::ByteOrder, |
243 | T: DynamicDeserialize<'d>, |
244 | { |
245 | let seed: ::Deserializer = T::deserializer_for_signature(signature)?; |
246 | |
247 | from_slice_with_seed(bytes, ctxt, seed) |
248 | } |
249 | |
250 | /// Deserialize `T` from a given slice of bytes containing file descriptor indices, with the given |
251 | /// signature. |
252 | /// |
253 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
254 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
255 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
256 | /// |
257 | /// This function is not available on Windows. |
258 | #[cfg (unix)] |
259 | pub fn from_slice_fds_for_dynamic_signature<'d, B, T>( |
260 | bytes: &'d [u8], |
261 | fds: Option<&[RawFd]>, |
262 | ctxt: EncodingContext<B>, |
263 | signature: &Signature<'d>, |
264 | ) -> Result<T> |
265 | where |
266 | B: byteorder::ByteOrder, |
267 | T: DynamicDeserialize<'d>, |
268 | { |
269 | let seed: ::Deserializer = T::deserializer_for_signature(signature)?; |
270 | |
271 | from_slice_fds_with_seed(bytes, fds, ctxt, seed) |
272 | } |
273 | |
274 | /// Deserialize `T` from a given slice of bytes containing file descriptor indices, using the given |
275 | /// seed. |
276 | /// |
277 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
278 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
279 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
280 | pub fn from_slice_with_seed<'d, B, S>( |
281 | bytes: &'d [u8], |
282 | ctxt: EncodingContext<B>, |
283 | seed: S, |
284 | ) -> Result<S::Value> |
285 | where |
286 | B: byteorder::ByteOrder, |
287 | S: DeserializeSeed<'d> + DynamicType, |
288 | { |
289 | _from_slice_fds_with_seed( |
290 | bytes, |
291 | #[cfg (unix)] |
292 | None, |
293 | ctxt, |
294 | seed, |
295 | ) |
296 | } |
297 | |
298 | /// Deserialize `T` from a given slice of bytes containing file descriptor indices, using the given |
299 | /// seed. |
300 | /// |
301 | /// Please note that actual file descriptors are not part of the encoding and need to be transferred |
302 | /// via an out-of-band platform specific mechanism. The encoding only contain the indices of the |
303 | /// file descriptors and hence the reason, caller must pass a slice of file descriptors. |
304 | /// |
305 | /// This function is not available on Windows. |
306 | #[cfg (unix)] |
307 | pub fn from_slice_fds_with_seed<'d, B, S>( |
308 | bytes: &'d [u8], |
309 | fds: Option<&[RawFd]>, |
310 | ctxt: EncodingContext<B>, |
311 | seed: S, |
312 | ) -> Result<S::Value> |
313 | where |
314 | B: byteorder::ByteOrder, |
315 | S: DeserializeSeed<'d> + DynamicType, |
316 | { |
317 | _from_slice_fds_with_seed(bytes, fds, ctxt, seed) |
318 | } |
319 | |
320 | fn _from_slice_fds_with_seed<'d, B, S>( |
321 | bytes: &'d [u8], |
322 | #[cfg (unix)] fds: Option<&[RawFd]>, |
323 | ctxt: EncodingContext<B>, |
324 | seed: S, |
325 | ) -> Result<S::Value> |
326 | where |
327 | B: byteorder::ByteOrder, |
328 | S: DeserializeSeed<'d> + DynamicType, |
329 | { |
330 | let signature: Signature<'_> = S::dynamic_signature(&seed).to_owned(); |
331 | |
332 | let mut de: Deserializer<'_, '_, '_, …> = match ctxt.format() { |
333 | #[cfg (feature = "gvariant" )] |
334 | EncodingFormat::GVariant => Deserializer::GVariant(GVDeserializer::new( |
335 | bytes, |
336 | #[cfg (unix)] |
337 | fds, |
338 | &signature, |
339 | ctxt, |
340 | )), |
341 | EncodingFormat::DBus => Deserializer::DBus(DBusDeserializer::new( |
342 | bytes, |
343 | #[cfg (unix)] |
344 | fds, |
345 | &signature, |
346 | ctxt, |
347 | )), |
348 | }; |
349 | |
350 | seed.deserialize(&mut de) |
351 | } |
352 | |
353 | /// Our deserialization implementation. |
354 | #[derive (Debug)] |
355 | pub(crate) struct DeserializerCommon<'de, 'sig, 'f, B> { |
356 | pub(crate) ctxt: EncodingContext<B>, |
357 | pub(crate) bytes: &'de [u8], |
358 | |
359 | #[cfg (unix)] |
360 | pub(crate) fds: Option<&'f [RawFd]>, |
361 | #[cfg (not(unix))] |
362 | pub(crate) fds: PhantomData<&'f ()>, |
363 | |
364 | pub(crate) pos: usize, |
365 | |
366 | pub(crate) sig_parser: SignatureParser<'sig>, |
367 | |
368 | pub(crate) container_depths: ContainerDepths, |
369 | |
370 | pub(crate) b: PhantomData<B>, |
371 | } |
372 | |
373 | /// Our deserialization implementation. |
374 | /// |
375 | /// Using this deserializer involves an redirection to the actual deserializer. It's best |
376 | /// to use the serialization functions, e.g [`crate::to_bytes`] or specific serializers, |
377 | /// [`crate::dbus::Deserializer`] or [`crate::zvariant::Deserializer`]. |
378 | pub enum Deserializer<'ser, 'sig, 'f, B> { |
379 | DBus(DBusDeserializer<'ser, 'sig, 'f, B>), |
380 | #[cfg (feature = "gvariant" )] |
381 | GVariant(GVDeserializer<'ser, 'sig, 'f, B>), |
382 | } |
383 | |
384 | assert_impl_all!(Deserializer<'_, '_, '_, u8>: Send, Sync, Unpin); |
385 | |
386 | impl<'de, 'sig, 'f, B> Deserializer<'de, 'sig, 'f, B> |
387 | where |
388 | B: byteorder::ByteOrder, |
389 | { |
390 | /// Create a Deserializer struct instance. |
391 | /// |
392 | /// On Windows, there is no `fds` argument. |
393 | pub fn new<'r: 'de>( |
394 | bytes: &'r [u8], |
395 | #[cfg (unix)] fds: Option<&'f [RawFd]>, |
396 | signature: &Signature<'sig>, |
397 | ctxt: EncodingContext<B>, |
398 | ) -> Self { |
399 | match ctxt.format() { |
400 | #[cfg (feature = "gvariant" )] |
401 | EncodingFormat::GVariant => Self::GVariant(GVDeserializer::new( |
402 | bytes, |
403 | #[cfg (unix)] |
404 | fds, |
405 | signature, |
406 | ctxt, |
407 | )), |
408 | EncodingFormat::DBus => Self::DBus(DBusDeserializer::new( |
409 | bytes, |
410 | #[cfg (unix)] |
411 | fds, |
412 | signature, |
413 | ctxt, |
414 | )), |
415 | } |
416 | } |
417 | } |
418 | |
419 | impl<'de, 'sig, 'f, B> DeserializerCommon<'de, 'sig, 'f, B> |
420 | where |
421 | B: byteorder::ByteOrder, |
422 | { |
423 | #[cfg (unix)] |
424 | pub fn get_fd(&self, idx: u32) -> Result<i32> { |
425 | self.fds |
426 | .and_then(|fds| fds.get(idx as usize)) |
427 | .copied() |
428 | .ok_or(Error::UnknownFd) |
429 | } |
430 | |
431 | pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> { |
432 | let padding = padding_for_n_bytes(self.abs_pos(), alignment); |
433 | if padding > 0 { |
434 | if self.pos + padding > self.bytes.len() { |
435 | return Err(serde::de::Error::invalid_length( |
436 | self.bytes.len(), |
437 | &format!(">= {}" , self.pos + padding).as_str(), |
438 | )); |
439 | } |
440 | |
441 | for i in 0..padding { |
442 | let byte = self.bytes[self.pos + i]; |
443 | if byte != 0 { |
444 | return Err(Error::PaddingNot0(byte)); |
445 | } |
446 | } |
447 | self.pos += padding; |
448 | } |
449 | |
450 | Ok(padding) |
451 | } |
452 | |
453 | pub fn prep_deserialize_basic<T>(&mut self) -> Result<()> |
454 | where |
455 | T: Basic, |
456 | { |
457 | self.sig_parser.skip_char()?; |
458 | self.parse_padding(T::alignment(self.ctxt.format()))?; |
459 | |
460 | Ok(()) |
461 | } |
462 | |
463 | pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> { |
464 | if self.pos + len > self.bytes.len() { |
465 | return Err(serde::de::Error::invalid_length( |
466 | self.bytes.len(), |
467 | &format!(">= {}" , self.pos + len).as_str(), |
468 | )); |
469 | } |
470 | |
471 | let slice = &self.bytes[self.pos..self.pos + len]; |
472 | self.pos += len; |
473 | |
474 | Ok(slice) |
475 | } |
476 | |
477 | pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]> |
478 | where |
479 | T: Basic, |
480 | { |
481 | self.prep_deserialize_basic::<T>()?; |
482 | |
483 | self.next_slice(T::alignment(self.ctxt.format())) |
484 | } |
485 | |
486 | pub fn abs_pos(&self) -> usize { |
487 | self.ctxt.position() + self.pos |
488 | } |
489 | } |
490 | |
491 | macro_rules! deserialize_method { |
492 | ($method:ident($($arg:ident: $type:ty),*)) => { |
493 | #[inline] |
494 | fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value> |
495 | where |
496 | V: Visitor<'de>, |
497 | { |
498 | match self { |
499 | #[cfg(feature = "gvariant" )] |
500 | Deserializer::GVariant(de) => { |
501 | de.$method($($arg,)* visitor) |
502 | } |
503 | Deserializer::DBus(de) => { |
504 | de.$method($($arg,)* visitor) |
505 | } |
506 | } |
507 | } |
508 | } |
509 | } |
510 | |
511 | impl<'de, 'd, 'sig, 'f, B> de::Deserializer<'de> for &'d mut Deserializer<'de, 'sig, 'f, B> |
512 | where |
513 | B: byteorder::ByteOrder, |
514 | { |
515 | type Error = Error; |
516 | |
517 | deserialize_method!(deserialize_any()); |
518 | deserialize_method!(deserialize_bool()); |
519 | deserialize_method!(deserialize_i8()); |
520 | deserialize_method!(deserialize_i16()); |
521 | deserialize_method!(deserialize_i32()); |
522 | deserialize_method!(deserialize_i64()); |
523 | deserialize_method!(deserialize_u8()); |
524 | deserialize_method!(deserialize_u16()); |
525 | deserialize_method!(deserialize_u32()); |
526 | deserialize_method!(deserialize_u64()); |
527 | deserialize_method!(deserialize_f32()); |
528 | deserialize_method!(deserialize_f64()); |
529 | deserialize_method!(deserialize_char()); |
530 | deserialize_method!(deserialize_str()); |
531 | deserialize_method!(deserialize_string()); |
532 | deserialize_method!(deserialize_bytes()); |
533 | deserialize_method!(deserialize_byte_buf()); |
534 | deserialize_method!(deserialize_option()); |
535 | deserialize_method!(deserialize_unit()); |
536 | deserialize_method!(deserialize_unit_struct(n: &'static str)); |
537 | deserialize_method!(deserialize_newtype_struct(n: &'static str)); |
538 | deserialize_method!(deserialize_seq()); |
539 | deserialize_method!(deserialize_map()); |
540 | deserialize_method!(deserialize_tuple(n: usize)); |
541 | deserialize_method!(deserialize_tuple_struct(n: &'static str, l: usize)); |
542 | deserialize_method!(deserialize_struct( |
543 | n: &'static str, |
544 | f: &'static [&'static str] |
545 | )); |
546 | deserialize_method!(deserialize_enum( |
547 | n: &'static str, |
548 | f: &'static [&'static str] |
549 | )); |
550 | deserialize_method!(deserialize_identifier()); |
551 | deserialize_method!(deserialize_ignored_any()); |
552 | |
553 | fn is_human_readable(&self) -> bool { |
554 | false |
555 | } |
556 | } |
557 | |
558 | #[derive (Debug)] |
559 | pub(crate) enum ValueParseStage { |
560 | Signature, |
561 | Value, |
562 | Done, |
563 | } |
564 | |
565 | pub(crate) fn deserialize_any<'de, 'sig, 'f, D, V>( |
566 | de: D, |
567 | next_char: char, |
568 | visitor: V, |
569 | ) -> Result<V::Value> |
570 | where |
571 | D: de::Deserializer<'de, Error = Error>, |
572 | V: Visitor<'de>, |
573 | { |
574 | match next_char { |
575 | u8::SIGNATURE_CHAR => de.deserialize_u8(visitor), |
576 | bool::SIGNATURE_CHAR => de.deserialize_bool(visitor), |
577 | i16::SIGNATURE_CHAR => de.deserialize_i16(visitor), |
578 | u16::SIGNATURE_CHAR => de.deserialize_u16(visitor), |
579 | i32::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
580 | #[cfg (unix)] |
581 | Fd::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
582 | u32::SIGNATURE_CHAR => de.deserialize_u32(visitor), |
583 | i64::SIGNATURE_CHAR => de.deserialize_i64(visitor), |
584 | u64::SIGNATURE_CHAR => de.deserialize_u64(visitor), |
585 | f64::SIGNATURE_CHAR => de.deserialize_f64(visitor), |
586 | <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR | Signature::SIGNATURE_CHAR => { |
587 | de.deserialize_str(visitor) |
588 | } |
589 | VARIANT_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
590 | ARRAY_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
591 | STRUCT_SIG_START_CHAR => de.deserialize_seq(visitor), |
592 | #[cfg (feature = "gvariant" )] |
593 | MAYBE_SIGNATURE_CHAR => de.deserialize_option(visitor), |
594 | c => Err(de::Error::invalid_value( |
595 | de::Unexpected::Char(c), |
596 | &"a valid signature character" , |
597 | )), |
598 | } |
599 | } |
600 | |
601 | // Enum handling is very generic so it can be here and specific deserializers can use this. |
602 | pub(crate) struct Enum<B, D> { |
603 | pub(crate) de: D, |
604 | pub(crate) name: &'static str, |
605 | pub(crate) phantom: PhantomData<B>, |
606 | } |
607 | |
608 | impl<'de, B, D> VariantAccess<'de> for Enum<B, D> |
609 | where |
610 | B: byteorder::ByteOrder, |
611 | D: de::Deserializer<'de, Error = Error>, |
612 | { |
613 | type Error = Error; |
614 | |
615 | fn unit_variant(self) -> std::result::Result<(), Self::Error> { |
616 | Ok(()) |
617 | } |
618 | |
619 | fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> |
620 | where |
621 | T: DeserializeSeed<'de>, |
622 | { |
623 | seed.deserialize(self.de) |
624 | } |
625 | |
626 | fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> |
627 | where |
628 | V: Visitor<'de>, |
629 | { |
630 | de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor) |
631 | } |
632 | |
633 | fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> |
634 | where |
635 | V: Visitor<'de>, |
636 | { |
637 | de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor) |
638 | } |
639 | } |
640 | |