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