1 | use byteorder::WriteBytesExt; |
2 | use serde::{ser, ser::SerializeSeq, Serialize}; |
3 | use static_assertions::assert_impl_all; |
4 | use std::{ |
5 | io::{Seek, Write}, |
6 | marker::PhantomData, |
7 | str, |
8 | }; |
9 | |
10 | #[cfg (unix)] |
11 | use std::os::unix::io::RawFd; |
12 | |
13 | use crate::{ |
14 | container_depths::ContainerDepths, signature_parser::SignatureParser, utils::*, Basic, |
15 | EncodingContext, EncodingFormat, Error, ObjectPath, Result, Signature, |
16 | }; |
17 | |
18 | #[cfg (unix)] |
19 | use crate::Fd; |
20 | |
21 | /// Our D-Bus serialization implementation. |
22 | pub struct Serializer<'ser, 'sig, B, W>(pub(crate) crate::SerializerCommon<'ser, 'sig, B, W>); |
23 | |
24 | assert_impl_all!(Serializer<'_, '_, i32, i32>: Send, Sync, Unpin); |
25 | |
26 | impl<'ser, 'sig, B, W> Serializer<'ser, 'sig, B, W> |
27 | where |
28 | B: byteorder::ByteOrder, |
29 | W: Write + Seek, |
30 | { |
31 | /// Create a D-Bus Serializer struct instance. |
32 | /// |
33 | /// On Windows, there is no `fds` argument. |
34 | pub fn new<'w: 'ser, 'f: 'ser>( |
35 | signature: &Signature<'sig>, |
36 | writer: &'w mut W, |
37 | #[cfg (unix)] fds: &'f mut Vec<RawFd>, |
38 | ctxt: EncodingContext<B>, |
39 | ) -> Self { |
40 | assert_eq!(ctxt.format(), EncodingFormat::DBus); |
41 | |
42 | let sig_parser = SignatureParser::new(signature.clone()); |
43 | Self(crate::SerializerCommon { |
44 | ctxt, |
45 | sig_parser, |
46 | writer, |
47 | #[cfg (unix)] |
48 | fds, |
49 | bytes_written: 0, |
50 | value_sign: None, |
51 | container_depths: Default::default(), |
52 | b: PhantomData, |
53 | }) |
54 | } |
55 | } |
56 | |
57 | macro_rules! serialize_basic { |
58 | ($method:ident($type:ty) $write_method:ident) => { |
59 | serialize_basic!($method($type) $write_method($type)); |
60 | }; |
61 | ($method:ident($type:ty) $write_method:ident($as:ty)) => { |
62 | fn $method(self, v: $type) -> Result<()> { |
63 | self.0.prep_serialize_basic::<$type>()?; |
64 | self.0.$write_method::<B>(v as $as).map_err(|e| Error::InputOutput(e.into())) |
65 | } |
66 | }; |
67 | } |
68 | |
69 | impl<'ser, 'sig, 'b, B, W> ser::Serializer for &'b mut Serializer<'ser, 'sig, B, W> |
70 | where |
71 | B: byteorder::ByteOrder, |
72 | W: Write + Seek, |
73 | { |
74 | type Ok = (); |
75 | type Error = Error; |
76 | |
77 | type SerializeSeq = SeqSerializer<'ser, 'sig, 'b, B, W>; |
78 | type SerializeTuple = StructSeqSerializer<'ser, 'sig, 'b, B, W>; |
79 | type SerializeTupleStruct = StructSeqSerializer<'ser, 'sig, 'b, B, W>; |
80 | type SerializeTupleVariant = StructSeqSerializer<'ser, 'sig, 'b, B, W>; |
81 | type SerializeMap = SeqSerializer<'ser, 'sig, 'b, B, W>; |
82 | type SerializeStruct = StructSeqSerializer<'ser, 'sig, 'b, B, W>; |
83 | type SerializeStructVariant = StructSeqSerializer<'ser, 'sig, 'b, B, W>; |
84 | |
85 | serialize_basic!(serialize_bool(bool) write_u32(u32)); |
86 | // No i8 type in D-Bus/GVariant, let's pretend it's i16 |
87 | serialize_basic!(serialize_i8(i8) write_i16(i16)); |
88 | serialize_basic!(serialize_i16(i16) write_i16); |
89 | serialize_basic!(serialize_i64(i64) write_i64); |
90 | |
91 | fn serialize_i32(self, v: i32) -> Result<()> { |
92 | match self.0.sig_parser.next_char()? { |
93 | #[cfg (unix)] |
94 | Fd::SIGNATURE_CHAR => { |
95 | self.0.sig_parser.skip_char()?; |
96 | self.0.add_padding(u32::alignment(EncodingFormat::DBus))?; |
97 | let v = self.0.add_fd(v); |
98 | self.0 |
99 | .write_u32::<B>(v) |
100 | .map_err(|e| Error::InputOutput(e.into())) |
101 | } |
102 | _ => { |
103 | self.0.prep_serialize_basic::<i32>()?; |
104 | self.0 |
105 | .write_i32::<B>(v) |
106 | .map_err(|e| Error::InputOutput(e.into())) |
107 | } |
108 | } |
109 | } |
110 | |
111 | fn serialize_u8(self, v: u8) -> Result<()> { |
112 | self.0.prep_serialize_basic::<u8>()?; |
113 | // Endianness is irrelevant for single bytes. |
114 | self.0.write_u8(v).map_err(|e| Error::InputOutput(e.into())) |
115 | } |
116 | |
117 | serialize_basic!(serialize_u16(u16) write_u16); |
118 | serialize_basic!(serialize_u32(u32) write_u32); |
119 | serialize_basic!(serialize_u64(u64) write_u64); |
120 | // No f32 type in D-Bus/GVariant, let's pretend it's f64 |
121 | serialize_basic!(serialize_f32(f32) write_f64(f64)); |
122 | serialize_basic!(serialize_f64(f64) write_f64); |
123 | |
124 | fn serialize_char(self, v: char) -> Result<()> { |
125 | // No char type in D-Bus, let's pretend it's a string |
126 | self.serialize_str(&v.to_string()) |
127 | } |
128 | |
129 | fn serialize_str(self, v: &str) -> Result<()> { |
130 | if v.contains(' \0' ) { |
131 | return Err(serde::de::Error::invalid_value( |
132 | serde::de::Unexpected::Char(' \0' ), |
133 | &"D-Bus string type must not contain interior null bytes" , |
134 | )); |
135 | } |
136 | let c = self.0.sig_parser.next_char()?; |
137 | if c == VARIANT_SIGNATURE_CHAR { |
138 | self.0.value_sign = Some(signature_string!(v)); |
139 | } |
140 | |
141 | match c { |
142 | ObjectPath::SIGNATURE_CHAR | <&str>::SIGNATURE_CHAR => { |
143 | self.0 |
144 | .add_padding(<&str>::alignment(EncodingFormat::DBus))?; |
145 | self.0 |
146 | .write_u32::<B>(usize_to_u32(v.len())) |
147 | .map_err(|e| Error::InputOutput(e.into()))?; |
148 | } |
149 | Signature::SIGNATURE_CHAR | VARIANT_SIGNATURE_CHAR => { |
150 | self.0 |
151 | .write_u8(usize_to_u8(v.len())) |
152 | .map_err(|e| Error::InputOutput(e.into()))?; |
153 | } |
154 | _ => { |
155 | let expected = format!( |
156 | "` {}`, ` {}`, ` {}` or ` {}`" , |
157 | <&str>::SIGNATURE_STR, |
158 | Signature::SIGNATURE_STR, |
159 | ObjectPath::SIGNATURE_STR, |
160 | VARIANT_SIGNATURE_CHAR, |
161 | ); |
162 | return Err(serde::de::Error::invalid_type( |
163 | serde::de::Unexpected::Char(c), |
164 | &expected.as_str(), |
165 | )); |
166 | } |
167 | } |
168 | |
169 | self.0.sig_parser.skip_char()?; |
170 | self.0 |
171 | .write_all(v.as_bytes()) |
172 | .map_err(|e| Error::InputOutput(e.into()))?; |
173 | self.0 |
174 | .write_all(&b" \0" [..]) |
175 | .map_err(|e| Error::InputOutput(e.into()))?; |
176 | |
177 | Ok(()) |
178 | } |
179 | |
180 | fn serialize_bytes(self, v: &[u8]) -> Result<()> { |
181 | let seq = self.serialize_seq(Some(v.len()))?; |
182 | seq.ser |
183 | .0 |
184 | .write(v) |
185 | .map_err(|e| Error::InputOutput(e.into()))?; |
186 | seq.end() |
187 | } |
188 | |
189 | fn serialize_none(self) -> Result<()> { |
190 | unreachable!("Option<T> can not be encoded in D-Bus format" ); |
191 | } |
192 | |
193 | fn serialize_some<T>(self, _value: &T) -> Result<()> |
194 | where |
195 | T: ?Sized + Serialize, |
196 | { |
197 | unreachable!("Option<T> can not be encoded in D-Bus format" ); |
198 | } |
199 | |
200 | fn serialize_unit(self) -> Result<()> { |
201 | Ok(()) |
202 | } |
203 | |
204 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { |
205 | self.serialize_unit() |
206 | } |
207 | |
208 | fn serialize_unit_variant( |
209 | self, |
210 | _name: &'static str, |
211 | variant_index: u32, |
212 | variant: &'static str, |
213 | ) -> Result<()> { |
214 | if self.0.sig_parser.next_char()? == <&str>::SIGNATURE_CHAR { |
215 | variant.serialize(self) |
216 | } else { |
217 | variant_index.serialize(self) |
218 | } |
219 | } |
220 | |
221 | fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()> |
222 | where |
223 | T: ?Sized + Serialize, |
224 | { |
225 | value.serialize(self)?; |
226 | |
227 | Ok(()) |
228 | } |
229 | |
230 | fn serialize_newtype_variant<T>( |
231 | self, |
232 | _name: &'static str, |
233 | variant_index: u32, |
234 | _variant: &'static str, |
235 | value: &T, |
236 | ) -> Result<()> |
237 | where |
238 | T: ?Sized + Serialize, |
239 | { |
240 | self.0.prep_serialize_enum_variant(variant_index)?; |
241 | value.serialize(&mut *self)?; |
242 | // Skip the `)`. |
243 | self.0.sig_parser.skip_char()?; |
244 | |
245 | Ok(()) |
246 | } |
247 | |
248 | fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { |
249 | self.0.sig_parser.skip_char()?; |
250 | self.0.add_padding(ARRAY_ALIGNMENT_DBUS)?; |
251 | // Length in bytes (unfortunately not the same as len passed to us here) which we |
252 | // initially set to 0. |
253 | self.0 |
254 | .write_u32::<B>(0_u32) |
255 | .map_err(|e| Error::InputOutput(e.into()))?; |
256 | |
257 | let element_signature = self.0.sig_parser.next_signature()?; |
258 | let element_signature_len = element_signature.len(); |
259 | let element_alignment = alignment_for_signature(&element_signature, self.0.ctxt.format())?; |
260 | |
261 | // D-Bus expects us to add padding for the first element even when there is no first |
262 | // element (i-e empty array) so we add padding already. |
263 | let first_padding = self.0.add_padding(element_alignment)?; |
264 | let start = self.0.bytes_written; |
265 | self.0.container_depths = self.0.container_depths.inc_array()?; |
266 | |
267 | Ok(SeqSerializer { |
268 | ser: self, |
269 | start, |
270 | element_alignment, |
271 | element_signature_len, |
272 | first_padding, |
273 | }) |
274 | } |
275 | |
276 | fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> { |
277 | self.serialize_struct("" , len) |
278 | } |
279 | |
280 | fn serialize_tuple_struct( |
281 | self, |
282 | name: &'static str, |
283 | len: usize, |
284 | ) -> Result<Self::SerializeTupleStruct> { |
285 | self.serialize_struct(name, len) |
286 | } |
287 | |
288 | fn serialize_tuple_variant( |
289 | self, |
290 | _name: &'static str, |
291 | variant_index: u32, |
292 | _variant: &'static str, |
293 | _len: usize, |
294 | ) -> Result<Self::SerializeTupleVariant> { |
295 | self.0.prep_serialize_enum_variant(variant_index)?; |
296 | |
297 | StructSerializer::enum_variant(self).map(StructSeqSerializer::Struct) |
298 | } |
299 | |
300 | fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> { |
301 | self.serialize_seq(len) |
302 | } |
303 | |
304 | fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> { |
305 | if len == 0 { |
306 | return StructSerializer::unit(self).map(StructSeqSerializer::Struct); |
307 | } |
308 | |
309 | match self.0.sig_parser.next_char()? { |
310 | VARIANT_SIGNATURE_CHAR => { |
311 | StructSerializer::variant(self).map(StructSeqSerializer::Struct) |
312 | } |
313 | ARRAY_SIGNATURE_CHAR => self.serialize_seq(Some(len)).map(StructSeqSerializer::Seq), |
314 | _ => StructSerializer::structure(self).map(StructSeqSerializer::Struct), |
315 | } |
316 | } |
317 | |
318 | fn serialize_struct_variant( |
319 | self, |
320 | _name: &'static str, |
321 | variant_index: u32, |
322 | _variant: &'static str, |
323 | _len: usize, |
324 | ) -> Result<Self::SerializeStructVariant> { |
325 | self.0.prep_serialize_enum_variant(variant_index)?; |
326 | |
327 | StructSerializer::enum_variant(self).map(StructSeqSerializer::Struct) |
328 | } |
329 | |
330 | fn is_human_readable(&self) -> bool { |
331 | false |
332 | } |
333 | } |
334 | |
335 | #[doc (hidden)] |
336 | pub struct SeqSerializer<'ser, 'sig, 'b, B, W> { |
337 | ser: &'b mut Serializer<'ser, 'sig, B, W>, |
338 | start: usize, |
339 | // alignment of element |
340 | element_alignment: usize, |
341 | // size of element signature |
342 | element_signature_len: usize, |
343 | // First element's padding |
344 | first_padding: usize, |
345 | } |
346 | |
347 | impl<'ser, 'sig, 'b, B, W> SeqSerializer<'ser, 'sig, 'b, B, W> |
348 | where |
349 | B: byteorder::ByteOrder, |
350 | W: Write + Seek, |
351 | { |
352 | pub(self) fn end_seq(self) -> Result<()> { |
353 | self.ser |
354 | .0 |
355 | .sig_parser |
356 | .skip_chars(self.element_signature_len)?; |
357 | |
358 | // Set size of array in bytes |
359 | let array_len = self.ser.0.bytes_written - self.start; |
360 | let len = usize_to_u32(array_len); |
361 | let total_array_len = (array_len + self.first_padding + 4) as i64; |
362 | self.ser |
363 | .0 |
364 | .writer |
365 | .seek(std::io::SeekFrom::Current(-total_array_len)) |
366 | .map_err(|e| Error::InputOutput(e.into()))?; |
367 | self.ser |
368 | .0 |
369 | .writer |
370 | .write_u32::<B>(len) |
371 | .map_err(|e| Error::InputOutput(e.into()))?; |
372 | self.ser |
373 | .0 |
374 | .writer |
375 | .seek(std::io::SeekFrom::Current(total_array_len - 4)) |
376 | .map_err(|e| Error::InputOutput(e.into()))?; |
377 | |
378 | self.ser.0.container_depths = self.ser.0.container_depths.dec_array(); |
379 | |
380 | Ok(()) |
381 | } |
382 | } |
383 | |
384 | impl<'ser, 'sig, 'b, B, W> ser::SerializeSeq for SeqSerializer<'ser, 'sig, 'b, B, W> |
385 | where |
386 | B: byteorder::ByteOrder, |
387 | W: Write + Seek, |
388 | { |
389 | type Ok = (); |
390 | type Error = Error; |
391 | |
392 | fn serialize_element<T>(&mut self, value: &T) -> Result<()> |
393 | where |
394 | T: ?Sized + Serialize, |
395 | { |
396 | // We want to keep parsing the same signature repeatedly for each element so we use a |
397 | // disposable clone. |
398 | let sig_parser: SignatureParser<'_> = self.ser.0.sig_parser.clone(); |
399 | self.ser.0.sig_parser = sig_parser.clone(); |
400 | |
401 | value.serialize(&mut *self.ser)?; |
402 | self.ser.0.sig_parser = sig_parser; |
403 | |
404 | Ok(()) |
405 | } |
406 | |
407 | fn end(self) -> Result<()> { |
408 | self.end_seq() |
409 | } |
410 | } |
411 | |
412 | #[doc (hidden)] |
413 | pub struct StructSerializer<'ser, 'sig, 'b, B, W> { |
414 | ser: &'b mut Serializer<'ser, 'sig, B, W>, |
415 | // The number of `)` in the signature to skip at the end. |
416 | end_parens: u8, |
417 | // The original container depths. We restore to that at the end. |
418 | container_depths: ContainerDepths, |
419 | } |
420 | |
421 | impl<'ser, 'sig, 'b, B, W> StructSerializer<'ser, 'sig, 'b, B, W> |
422 | where |
423 | B: byteorder::ByteOrder, |
424 | W: Write + Seek, |
425 | { |
426 | fn variant(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> { |
427 | ser.0.add_padding(VARIANT_ALIGNMENT_DBUS)?; |
428 | let container_depths = ser.0.container_depths; |
429 | ser.0.container_depths = ser.0.container_depths.inc_variant()?; |
430 | |
431 | Ok(Self { |
432 | ser, |
433 | end_parens: 0, |
434 | container_depths, |
435 | }) |
436 | } |
437 | |
438 | fn structure(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> { |
439 | let c = ser.0.sig_parser.next_char()?; |
440 | if c != STRUCT_SIG_START_CHAR && c != DICT_ENTRY_SIG_START_CHAR { |
441 | let expected = format!("` {STRUCT_SIG_START_STR}` or ` {DICT_ENTRY_SIG_START_STR}`" ,); |
442 | |
443 | return Err(serde::de::Error::invalid_type( |
444 | serde::de::Unexpected::Char(c), |
445 | &expected.as_str(), |
446 | )); |
447 | } |
448 | |
449 | let signature = ser.0.sig_parser.next_signature()?; |
450 | let alignment = alignment_for_signature(&signature, EncodingFormat::DBus)?; |
451 | ser.0.add_padding(alignment)?; |
452 | |
453 | ser.0.sig_parser.skip_char()?; |
454 | let container_depths = ser.0.container_depths; |
455 | ser.0.container_depths = ser.0.container_depths.inc_structure()?; |
456 | |
457 | Ok(Self { |
458 | ser, |
459 | end_parens: 1, |
460 | container_depths, |
461 | }) |
462 | } |
463 | |
464 | fn unit(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> { |
465 | // serialize as a `0u8` |
466 | serde::Serializer::serialize_u8(&mut *ser, 0)?; |
467 | |
468 | let container_depths = ser.0.container_depths; |
469 | Ok(Self { |
470 | ser, |
471 | end_parens: 0, |
472 | container_depths, |
473 | }) |
474 | } |
475 | |
476 | fn enum_variant(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> { |
477 | let mut ser = Self::structure(ser)?; |
478 | ser.end_parens += 1; |
479 | |
480 | Ok(ser) |
481 | } |
482 | |
483 | fn serialize_struct_element<T>(&mut self, name: Option<&'static str>, value: &T) -> Result<()> |
484 | where |
485 | T: ?Sized + Serialize, |
486 | { |
487 | match name { |
488 | Some("zvariant::Value::Value" ) => { |
489 | // Serializing the value of a Value, which means signature was serialized |
490 | // already, and also put aside for us to be picked here. |
491 | let signature = self |
492 | .ser |
493 | .0 |
494 | .value_sign |
495 | .take() |
496 | .expect("Incorrect Value encoding" ); |
497 | |
498 | let sig_parser = SignatureParser::new(signature); |
499 | let bytes_written = self.ser.0.bytes_written; |
500 | let mut ser = Serializer(crate::SerializerCommon::<B, W> { |
501 | ctxt: self.ser.0.ctxt, |
502 | sig_parser, |
503 | writer: self.ser.0.writer, |
504 | #[cfg (unix)] |
505 | fds: self.ser.0.fds, |
506 | bytes_written, |
507 | value_sign: None, |
508 | container_depths: self.ser.0.container_depths, |
509 | b: PhantomData, |
510 | }); |
511 | value.serialize(&mut ser)?; |
512 | self.ser.0.bytes_written = ser.0.bytes_written; |
513 | |
514 | Ok(()) |
515 | } |
516 | _ => value.serialize(&mut *self.ser), |
517 | } |
518 | } |
519 | |
520 | fn end_struct(self) -> Result<()> { |
521 | if self.end_parens > 0 { |
522 | self.ser.0.sig_parser.skip_chars(self.end_parens as usize)?; |
523 | } |
524 | // Restore the original container depths. |
525 | self.ser.0.container_depths = self.container_depths; |
526 | |
527 | Ok(()) |
528 | } |
529 | } |
530 | |
531 | #[doc (hidden)] |
532 | /// Allows us to serialize a struct as an ARRAY. |
533 | pub enum StructSeqSerializer<'ser, 'sig, 'b, B, W> { |
534 | Struct(StructSerializer<'ser, 'sig, 'b, B, W>), |
535 | Seq(SeqSerializer<'ser, 'sig, 'b, B, W>), |
536 | } |
537 | |
538 | macro_rules! serialize_struct_anon_fields { |
539 | ($trait:ident $method:ident) => { |
540 | impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W> |
541 | where |
542 | B: byteorder::ByteOrder, |
543 | W: Write + Seek, |
544 | { |
545 | type Ok = (); |
546 | type Error = Error; |
547 | |
548 | fn $method<T>(&mut self, value: &T) -> Result<()> |
549 | where |
550 | T: ?Sized + Serialize, |
551 | { |
552 | self.serialize_struct_element(None, value) |
553 | } |
554 | |
555 | fn end(self) -> Result<()> { |
556 | self.end_struct() |
557 | } |
558 | } |
559 | |
560 | impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSeqSerializer<'ser, 'sig, 'b, B, W> |
561 | where |
562 | B: byteorder::ByteOrder, |
563 | W: Write + Seek, |
564 | { |
565 | type Ok = (); |
566 | type Error = Error; |
567 | |
568 | fn $method<T>(&mut self, value: &T) -> Result<()> |
569 | where |
570 | T: ?Sized + Serialize, |
571 | { |
572 | match self { |
573 | StructSeqSerializer::Struct(ser) => ser.$method(value), |
574 | StructSeqSerializer::Seq(ser) => ser.serialize_element(value), |
575 | } |
576 | } |
577 | |
578 | fn end(self) -> Result<()> { |
579 | match self { |
580 | StructSeqSerializer::Struct(ser) => ser.end_struct(), |
581 | StructSeqSerializer::Seq(ser) => ser.end_seq(), |
582 | } |
583 | } |
584 | } |
585 | }; |
586 | } |
587 | serialize_struct_anon_fields!(SerializeTuple serialize_element); |
588 | serialize_struct_anon_fields!(SerializeTupleStruct serialize_field); |
589 | serialize_struct_anon_fields!(SerializeTupleVariant serialize_field); |
590 | |
591 | impl<'ser, 'sig, 'b, B, W> ser::SerializeMap for SeqSerializer<'ser, 'sig, 'b, B, W> |
592 | where |
593 | B: byteorder::ByteOrder, |
594 | W: Write + Seek, |
595 | { |
596 | type Ok = (); |
597 | type Error = Error; |
598 | |
599 | fn serialize_key<T>(&mut self, key: &T) -> Result<()> |
600 | where |
601 | T: ?Sized + Serialize, |
602 | { |
603 | self.ser.0.add_padding(self.element_alignment)?; |
604 | |
605 | // We want to keep parsing the same signature repeatedly for each key so we use a |
606 | // disposable clone. |
607 | let sig_parser = self.ser.0.sig_parser.clone(); |
608 | self.ser.0.sig_parser = sig_parser.clone(); |
609 | |
610 | // skip `{` |
611 | self.ser.0.sig_parser.skip_char()?; |
612 | |
613 | key.serialize(&mut *self.ser)?; |
614 | self.ser.0.sig_parser = sig_parser; |
615 | |
616 | Ok(()) |
617 | } |
618 | |
619 | fn serialize_value<T>(&mut self, value: &T) -> Result<()> |
620 | where |
621 | T: ?Sized + Serialize, |
622 | { |
623 | // We want to keep parsing the same signature repeatedly for each key so we use a |
624 | // disposable clone. |
625 | let sig_parser = self.ser.0.sig_parser.clone(); |
626 | self.ser.0.sig_parser = sig_parser.clone(); |
627 | |
628 | // skip `{` and key char |
629 | self.ser.0.sig_parser.skip_chars(2)?; |
630 | |
631 | value.serialize(&mut *self.ser)?; |
632 | // Restore the original parser |
633 | self.ser.0.sig_parser = sig_parser; |
634 | |
635 | Ok(()) |
636 | } |
637 | |
638 | fn end(self) -> Result<()> { |
639 | self.end_seq() |
640 | } |
641 | } |
642 | |
643 | macro_rules! serialize_struct_named_fields { |
644 | ($trait:ident) => { |
645 | impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W> |
646 | where |
647 | B: byteorder::ByteOrder, |
648 | W: Write + Seek, |
649 | { |
650 | type Ok = (); |
651 | type Error = Error; |
652 | |
653 | fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> |
654 | where |
655 | T: ?Sized + Serialize, |
656 | { |
657 | self.serialize_struct_element(Some(key), value) |
658 | } |
659 | |
660 | fn end(self) -> Result<()> { |
661 | self.end_struct() |
662 | } |
663 | } |
664 | |
665 | impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSeqSerializer<'ser, 'sig, 'b, B, W> |
666 | where |
667 | B: byteorder::ByteOrder, |
668 | W: Write + Seek, |
669 | { |
670 | type Ok = (); |
671 | type Error = Error; |
672 | |
673 | fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> |
674 | where |
675 | T: ?Sized + Serialize, |
676 | { |
677 | match self { |
678 | StructSeqSerializer::Struct(ser) => ser.serialize_field(key, value), |
679 | StructSeqSerializer::Seq(ser) => ser.serialize_element(value), |
680 | } |
681 | } |
682 | |
683 | fn end(self) -> Result<()> { |
684 | match self { |
685 | StructSeqSerializer::Struct(ser) => ser.end_struct(), |
686 | StructSeqSerializer::Seq(ser) => ser.end_seq(), |
687 | } |
688 | } |
689 | } |
690 | }; |
691 | } |
692 | serialize_struct_named_fields!(SerializeStruct); |
693 | serialize_struct_named_fields!(SerializeStructVariant); |
694 | |