1use serde::{
2 ser::{self, SerializeMap, SerializeSeq, SerializeTuple},
3 Serialize,
4};
5use std::{
6 io::{Seek, Write},
7 str::{self, FromStr},
8};
9
10use crate::{
11 container_depths::ContainerDepths,
12 serialized::{Context, Format},
13 utils::*,
14 Basic, Error, ObjectPath, Result, Signature, WriteBytes,
15};
16
17pub(crate) struct Serializer<'ser, W>(pub(crate) crate::SerializerCommon<'ser, W>);
19
20impl<'ser, W> Serializer<'ser, W>
21where
22 W: Write + Seek,
23{
24 pub fn new<'w: 'ser, 'f: 'ser>(
28 signature: &'ser Signature,
29 writer: &'w mut W,
30 #[cfg(unix)] fds: &'f mut crate::ser::FdList,
31 ctxt: Context,
32 ) -> Result<Self> {
33 assert_eq!(ctxt.format(), Format::DBus);
34
35 Ok(Self(crate::SerializerCommon {
36 ctxt,
37 signature,
38 writer,
39 #[cfg(unix)]
40 fds,
41 bytes_written: 0,
42 value_sign: None,
43 container_depths: Default::default(),
44 }))
45 }
46}
47
48macro_rules! serialize_basic {
49 ($method:ident($type:ty) $write_method:ident) => {
50 serialize_basic!($method($type) $write_method($type));
51 };
52 ($method:ident($type:ty) $write_method:ident($as:ty)) => {
53 fn $method(self, v: $type) -> Result<()> {
54 self.0.prep_serialize_basic::<$type>()?;
55 self.0.$write_method(self.0.ctxt.endian(), v as $as).map_err(|e| Error::InputOutput(e.into()))
56 }
57 };
58}
59
60impl<'ser, 'b, W> ser::Serializer for &'b mut Serializer<'ser, W>
61where
62 W: Write + Seek,
63{
64 type Ok = ();
65 type Error = Error;
66
67 type SerializeSeq = SeqSerializer<'ser, 'b, W>;
68 type SerializeTuple = StructSeqSerializer<'ser, 'b, W>;
69 type SerializeTupleStruct = StructSeqSerializer<'ser, 'b, W>;
70 type SerializeTupleVariant = StructSeqSerializer<'ser, 'b, W>;
71 type SerializeMap = MapSerializer<'ser, 'b, W>;
72 type SerializeStruct = StructSeqSerializer<'ser, 'b, W>;
73 type SerializeStructVariant = StructSeqSerializer<'ser, 'b, W>;
74
75 serialize_basic!(serialize_bool(bool) write_u32(u32));
76 serialize_basic!(serialize_i8(i8) write_i16(i16));
78 serialize_basic!(serialize_i16(i16) write_i16);
79 serialize_basic!(serialize_i64(i64) write_i64);
80
81 fn serialize_i32(self, v: i32) -> Result<()> {
82 match &self.0.signature {
83 #[cfg(unix)]
84 Signature::Fd => {
85 self.0.add_padding(u32::alignment(Format::DBus))?;
86 let idx = self.0.add_fd(v)?;
87 self.0
88 .write_u32(self.0.ctxt.endian(), idx)
89 .map_err(|e| Error::InputOutput(e.into()))
90 }
91 _ => {
92 self.0.prep_serialize_basic::<i32>()?;
93 self.0
94 .write_i32(self.0.ctxt.endian(), v)
95 .map_err(|e| Error::InputOutput(e.into()))
96 }
97 }
98 }
99
100 fn serialize_u8(self, v: u8) -> Result<()> {
101 self.0.prep_serialize_basic::<u8>()?;
102 self.0
104 .write_u8(self.0.ctxt.endian(), v)
105 .map_err(|e| Error::InputOutput(e.into()))
106 }
107
108 serialize_basic!(serialize_u16(u16) write_u16);
109 serialize_basic!(serialize_u32(u32) write_u32);
110 serialize_basic!(serialize_u64(u64) write_u64);
111 serialize_basic!(serialize_f32(f32) write_f64(f64));
113 serialize_basic!(serialize_f64(f64) write_f64);
114
115 fn serialize_char(self, v: char) -> Result<()> {
116 self.serialize_str(&v.to_string())
118 }
119
120 fn serialize_str(self, v: &str) -> Result<()> {
121 self.0
122 .add_padding(self.0.signature.alignment(Format::DBus))?;
123
124 let signature = self.0.signature;
125 if matches!(signature, Signature::Variant) {
126 self.0.value_sign = Some(Signature::from_str(v)?);
127 }
128
129 match signature {
130 Signature::ObjectPath | Signature::Str => {
131 self.0
132 .write_u32(self.0.ctxt.endian(), usize_to_u32(v.len()))
133 .map_err(|e| Error::InputOutput(e.into()))?;
134 }
135 Signature::Signature | Signature::Variant => {
136 self.0
137 .write_u8(self.0.ctxt.endian(), usize_to_u8(v.len()))
138 .map_err(|e| Error::InputOutput(e.into()))?;
139 }
140 _ => {
141 let expected = format!(
142 "`{}`, `{}`, `{}` or `{}`",
143 <&str>::SIGNATURE_STR,
144 Signature::SIGNATURE_STR,
145 ObjectPath::SIGNATURE_STR,
146 VARIANT_SIGNATURE_CHAR,
147 );
148 return Err(Error::SignatureMismatch(signature.clone(), expected));
149 }
150 }
151
152 self.0
153 .write_all(v.as_bytes())
154 .map_err(|e| Error::InputOutput(e.into()))?;
155 self.0
156 .write_all(&b"\0"[..])
157 .map_err(|e| Error::InputOutput(e.into()))?;
158
159 Ok(())
160 }
161
162 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
163 self.0.add_padding(ARRAY_ALIGNMENT_DBUS)?;
164 self.0
165 .write_u32(self.0.ctxt.endian(), v.len() as u32)
166 .map_err(|e| Error::InputOutput(e.into()))?;
167 self.0
168 .write(v)
169 .map(|_| ())
170 .map_err(|e| Error::InputOutput(e.into()))
171 }
172
173 fn serialize_none(self) -> Result<()> {
174 #[cfg(feature = "option-as-array")]
175 {
176 let seq = self.serialize_seq(Some(0))?;
177 seq.end()
178 }
179
180 #[cfg(not(feature = "option-as-array"))]
181 unreachable!(
182 "Can only encode Option<T> in D-Bus format if `option-as-array` feature is enabled",
183 );
184 }
185
186 fn serialize_some<T>(self, #[allow(unused)] value: &T) -> Result<()>
187 where
188 T: ?Sized + Serialize,
189 {
190 #[cfg(feature = "option-as-array")]
191 {
192 let mut seq = self.serialize_seq(Some(1))?;
193 seq.serialize_element(value)?;
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_unit(self) -> Result<()> {
204 Ok(())
205 }
206
207 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
208 self.serialize_unit()
209 }
210
211 fn serialize_unit_variant(
212 self,
213 _name: &'static str,
214 variant_index: u32,
215 variant: &'static str,
216 ) -> Result<()> {
217 if matches!(self.0.signature, Signature::Str) {
218 variant.serialize(self)
219 } else {
220 variant_index.serialize(self)
221 }
222 }
223
224 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
225 where
226 T: ?Sized + Serialize,
227 {
228 value.serialize(self)?;
229
230 Ok(())
231 }
232
233 fn serialize_newtype_variant<T>(
234 self,
235 _name: &'static str,
236 variant_index: u32,
237 _variant: &'static str,
238 value: &T,
239 ) -> Result<()>
240 where
241 T: ?Sized + Serialize,
242 {
243 StructSerializer::enum_variant(self, variant_index)
244 .and_then(|mut ser| ser.serialize_element(value))
245 }
246
247 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
248 self.0.add_padding(ARRAY_ALIGNMENT_DBUS)?;
249 self.0
252 .write_u32(self.0.ctxt.endian(), 0_u32)
253 .map_err(|e| Error::InputOutput(e.into()))?;
254
255 let (alignment, child_signature) = match self.0.signature {
258 Signature::Array(child) => (child.alignment(self.0.ctxt.format()), child.signature()),
259 Signature::Dict { key, .. } => (DICT_ENTRY_ALIGNMENT_DBUS, key.signature()),
260 _ => {
261 return Err(Error::SignatureMismatch(
262 self.0.signature.clone(),
263 "an array or dict".to_string(),
264 ));
265 }
266 };
267
268 let array_signature = self.0.signature;
273 self.0.signature = child_signature;
274 let first_padding = self.0.add_padding(alignment)?;
275 let start = self.0.bytes_written;
276 self.0.container_depths = self.0.container_depths.inc_array()?;
277
278 Ok(SeqSerializer {
279 ser: self,
280 start,
281 first_padding,
282 array_signature,
283 })
284 }
285
286 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
287 self.serialize_struct("", len)
288 }
289
290 fn serialize_tuple_struct(
291 self,
292 name: &'static str,
293 len: usize,
294 ) -> Result<Self::SerializeTupleStruct> {
295 self.serialize_struct(name, len)
296 }
297
298 fn serialize_tuple_variant(
299 self,
300 _name: &'static str,
301 variant_index: u32,
302 _variant: &'static str,
303 _len: usize,
304 ) -> Result<Self::SerializeTupleVariant> {
305 StructSerializer::enum_variant(self, variant_index).map(StructSeqSerializer::Struct)
306 }
307
308 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
309 let (key_signature, value_signature) = match self.0.signature {
310 Signature::Dict { key, value } => (key.signature(), value.signature()),
311 _ => {
312 return Err(Error::SignatureMismatch(
313 self.0.signature.clone(),
314 "a dict".to_string(),
315 ));
316 }
317 };
318
319 let seq = self.serialize_seq(len)?;
320
321 Ok(MapSerializer {
322 seq,
323 key_signature,
324 value_signature,
325 })
326 }
327
328 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
329 self.0
330 .add_padding(self.0.signature.alignment(self.0.ctxt.format()))?;
331 match &self.0.signature {
332 Signature::Variant => StructSerializer::variant(self).map(StructSeqSerializer::Struct),
333 Signature::Array(_) => self.serialize_seq(Some(len)).map(StructSeqSerializer::Seq),
334 Signature::U8 => StructSerializer::unit(self).map(StructSeqSerializer::Struct),
335 Signature::Structure(_) => {
336 StructSerializer::structure(self).map(StructSeqSerializer::Struct)
337 }
338 Signature::Dict { .. } => self.serialize_map(Some(len)).map(StructSeqSerializer::Map),
339 _ => Err(Error::SignatureMismatch(
340 self.0.signature.clone(),
341 "a struct, array, u8 or variant".to_string(),
342 )),
343 }
344 }
345
346 fn serialize_struct_variant(
347 self,
348 _name: &'static str,
349 variant_index: u32,
350 _variant: &'static str,
351 _len: usize,
352 ) -> Result<Self::SerializeStructVariant> {
353 StructSerializer::enum_variant(self, variant_index).map(StructSeqSerializer::Struct)
354 }
355
356 fn is_human_readable(&self) -> bool {
357 false
358 }
359}
360
361#[doc(hidden)]
362pub struct SeqSerializer<'ser, 'b, W> {
363 ser: &'b mut Serializer<'ser, W>,
364 start: usize,
365 first_padding: usize,
367 array_signature: &'ser Signature,
368}
369
370impl<W> SeqSerializer<'_, '_, W>
371where
372 W: Write + Seek,
373{
374 pub(self) fn end_seq(self) -> Result<()> {
375 let array_len = self.ser.0.bytes_written - self.start;
377 let len = usize_to_u32(array_len);
378 let total_array_len = (array_len + self.first_padding + 4) as i64;
379 self.ser
380 .0
381 .writer
382 .seek(std::io::SeekFrom::Current(-total_array_len))
383 .map_err(|e| Error::InputOutput(e.into()))?;
384 self.ser
385 .0
386 .writer
387 .write_u32(self.ser.0.ctxt.endian(), len)
388 .map_err(|e| Error::InputOutput(e.into()))?;
389 self.ser
390 .0
391 .writer
392 .seek(std::io::SeekFrom::Current(total_array_len - 4))
393 .map_err(|e| Error::InputOutput(e.into()))?;
394
395 self.ser.0.container_depths = self.ser.0.container_depths.dec_array();
396 self.ser.0.signature = self.array_signature;
397
398 Ok(())
399 }
400}
401
402impl<W> ser::SerializeSeq for SeqSerializer<'_, '_, W>
403where
404 W: Write + Seek,
405{
406 type Ok = ();
407 type Error = Error;
408
409 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
410 where
411 T: ?Sized + Serialize,
412 {
413 value.serialize(&mut *self.ser)
414 }
415
416 fn end(self) -> Result<()> {
417 self.end_seq()
418 }
419}
420
421#[doc(hidden)]
422pub struct StructSerializer<'ser, 'b, W> {
423 ser: &'b mut Serializer<'ser, W>,
424 container_depths: ContainerDepths,
426 field_idx: usize,
428}
429
430impl<'ser, 'b, W> StructSerializer<'ser, 'b, W>
431where
432 W: Write + Seek,
433{
434 fn variant(ser: &'b mut Serializer<'ser, W>) -> Result<Self> {
435 let container_depths = ser.0.container_depths;
436 ser.0.container_depths = ser.0.container_depths.inc_variant()?;
437
438 Ok(Self {
439 ser,
440 container_depths,
441 field_idx: 0,
442 })
443 }
444
445 fn structure(ser: &'b mut Serializer<'ser, W>) -> Result<Self> {
446 let container_depths = ser.0.container_depths;
447 ser.0.container_depths = ser.0.container_depths.inc_structure()?;
448
449 Ok(Self {
450 ser,
451 container_depths,
452 field_idx: 0,
453 })
454 }
455
456 fn unit(ser: &'b mut Serializer<'ser, W>) -> Result<Self> {
457 serde::Serializer::serialize_u8(&mut *ser, 0)?;
459
460 let container_depths = ser.0.container_depths;
461 Ok(Self {
462 ser,
463 container_depths,
464 field_idx: 0,
465 })
466 }
467
468 fn enum_variant(ser: &'b mut Serializer<'ser, W>, variant_index: u32) -> Result<Self> {
469 let Signature::Structure(fields) = ser.0.signature else {
471 return Err(Error::SignatureMismatch(
472 ser.0.signature.clone(),
473 "a struct".to_string(),
474 ));
475 };
476 let struct_field = fields.iter().nth(1).and_then(|f| {
477 if matches!(f, Signature::Structure(_)) {
478 Some(f)
479 } else {
480 None
481 }
482 });
483
484 ser.0.add_padding(STRUCT_ALIGNMENT_DBUS)?;
485 let mut struct_ser = Self::structure(ser)?;
486 struct_ser.serialize_struct_element(&variant_index)?;
487
488 if let Some(field) = struct_field {
489 struct_ser.ser.0.add_padding(STRUCT_ALIGNMENT_DBUS)?;
491 struct_ser.field_idx = 0;
492 struct_ser.ser.0.signature = field;
493 }
494
495 Ok(struct_ser)
496 }
497
498 fn serialize_struct_element<T>(&mut self, value: &T) -> Result<()>
499 where
500 T: ?Sized + Serialize,
501 {
502 let signature = self.ser.0.signature;
503 let field_signature = match signature {
504 Signature::Variant => {
505 match &self.ser.0.value_sign {
506 Some(signature) => signature,
509 None => &Signature::Variant,
511 }
512 }
513 Signature::Structure(fields) => {
514 let signature = fields.iter().nth(self.field_idx).ok_or_else(|| {
515 Error::SignatureMismatch(signature.clone(), "a struct".to_string())
516 })?;
517 self.field_idx += 1;
518
519 signature
520 }
521 _ => unreachable!("Incorrect signature for struct"),
522 };
523 let bytes_written = self.ser.0.bytes_written;
524 let mut ser = Serializer(crate::SerializerCommon::<W> {
525 ctxt: self.ser.0.ctxt,
526 signature: field_signature,
527 writer: self.ser.0.writer,
528 #[cfg(unix)]
529 fds: self.ser.0.fds,
530 bytes_written,
531 value_sign: None,
532 container_depths: self.ser.0.container_depths,
533 });
534
535 value.serialize(&mut ser)?;
536 self.ser.0.bytes_written = ser.0.bytes_written;
537 self.ser.0.value_sign = ser.0.value_sign;
538
539 Ok(())
540 }
541
542 fn end_struct(self) -> Result<()> {
543 self.ser.0.container_depths = self.container_depths;
545
546 Ok(())
547 }
548}
549
550#[doc(hidden)]
551pub enum StructSeqSerializer<'ser, 'b, W> {
553 Struct(StructSerializer<'ser, 'b, W>),
554 Seq(SeqSerializer<'ser, 'b, W>),
555 Map(MapSerializer<'ser, 'b, W>),
556}
557
558macro_rules! serialize_struct_anon_fields {
559 ($trait:ident $method:ident) => {
560 impl<'ser, 'b, W> ser::$trait for StructSerializer<'ser, 'b, W>
561 where
562 W: Write + Seek,
563 {
564 type Ok = ();
565 type Error = Error;
566
567 fn $method<T>(&mut self, value: &T) -> Result<()>
568 where
569 T: ?Sized + Serialize,
570 {
571 self.serialize_struct_element(value)
572 }
573
574 fn end(self) -> Result<()> {
575 self.end_struct()
576 }
577 }
578
579 impl<'ser, 'b, W> ser::$trait for StructSeqSerializer<'ser, 'b, W>
580 where
581 W: Write + Seek,
582 {
583 type Ok = ();
584 type Error = Error;
585
586 fn $method<T>(&mut self, value: &T) -> Result<()>
587 where
588 T: ?Sized + Serialize,
589 {
590 match self {
591 StructSeqSerializer::Struct(ser) => ser.$method(value),
592 StructSeqSerializer::Seq(ser) => ser.serialize_element(value),
593 StructSeqSerializer::Map(_) => unreachable!(),
594 }
595 }
596
597 fn end(self) -> Result<()> {
598 match self {
599 StructSeqSerializer::Struct(ser) => ser.end_struct(),
600 StructSeqSerializer::Seq(ser) => ser.end_seq(),
601 StructSeqSerializer::Map(_) => unreachable!(),
602 }
603 }
604 }
605 };
606}
607serialize_struct_anon_fields!(SerializeTuple serialize_element);
608serialize_struct_anon_fields!(SerializeTupleStruct serialize_field);
609serialize_struct_anon_fields!(SerializeTupleVariant serialize_field);
610
611pub struct MapSerializer<'ser, 'b, W> {
612 seq: SeqSerializer<'ser, 'b, W>,
613 key_signature: &'ser Signature,
614 value_signature: &'ser Signature,
615}
616
617impl<W> SerializeMap for MapSerializer<'_, '_, W>
618where
619 W: Write + Seek,
620{
621 type Ok = ();
622 type Error = Error;
623
624 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
625 where
626 T: ?Sized + Serialize,
627 {
628 self.seq.ser.0.add_padding(DICT_ENTRY_ALIGNMENT_DBUS)?;
629
630 key.serialize(&mut *self.seq.ser)
631 }
632
633 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
634 where
635 T: ?Sized + Serialize,
636 {
637 self.seq.ser.0.signature = self.value_signature;
638 value.serialize(&mut *self.seq.ser)?;
639 self.seq.ser.0.signature = self.key_signature;
640
641 Ok(())
642 }
643
644 fn end(self) -> Result<()> {
645 self.seq.end_seq()
646 }
647}
648
649macro_rules! serialize_struct_named_fields {
650 ($trait:ident) => {
651 impl<'ser, 'b, W> ser::$trait for StructSerializer<'ser, 'b, W>
652 where
653 W: Write + Seek,
654 {
655 type Ok = ();
656 type Error = Error;
657
658 fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
659 where
660 T: ?Sized + Serialize,
661 {
662 self.serialize_struct_element(value)
663 }
664
665 fn end(self) -> Result<()> {
666 self.end_struct()
667 }
668 }
669
670 impl<'ser, 'b, W> ser::$trait for StructSeqSerializer<'ser, 'b, W>
671 where
672 W: Write + Seek,
673 {
674 type Ok = ();
675 type Error = Error;
676
677 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
678 where
679 T: ?Sized + Serialize,
680 {
681 match self {
682 StructSeqSerializer::Struct(ser) => ser.serialize_field(key, value),
683 StructSeqSerializer::Seq(ser) => ser.serialize_element(value),
684 StructSeqSerializer::Map(ser) => {
685 ser.serialize_key(key)?;
686 ser.serialize_value(value)
687 }
688 }
689 }
690
691 fn end(self) -> Result<()> {
692 match self {
693 StructSeqSerializer::Struct(ser) => ser.end_struct(),
694 StructSeqSerializer::Seq(ser) => ser.end_seq(),
695 StructSeqSerializer::Map(ser) => ser.end(),
696 }
697 }
698 }
699 };
700}
701serialize_struct_named_fields!(SerializeStruct);
702serialize_struct_named_fields!(SerializeStructVariant);