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