1use serde::{ser, ser::SerializeSeq, Serialize};
2use static_assertions::assert_impl_all;
3use std::{
4 io::{Seek, Write},
5 str,
6};
7
8use 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)]
17use crate::Fd;
18
19pub(crate) struct Serializer<'ser, 'sig, W>(pub(crate) crate::SerializerCommon<'ser, 'sig, W>);
21
22assert_impl_all!(Serializer<'_, '_, i32>: Send, Sync, Unpin);
23
24impl<'ser, 'sig, W> Serializer<'ser, 'sig, W>
25where
26 W: Write + Seek,
27{
28 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
58macro_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
70impl<'ser, 'sig, 'b, W> ser::Serializer for &'b mut Serializer<'ser, 'sig, W>
71where
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 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 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 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 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 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 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 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)]
356pub struct SeqSerializer<'ser, 'sig, 'b, W> {
357 ser: &'b mut Serializer<'ser, 'sig, W>,
358 start: usize,
359 element_alignment: usize,
361 element_signature_len: usize,
363 first_padding: usize,
365}
366
367impl<'ser, 'sig, 'b, W> SeqSerializer<'ser, 'sig, 'b, W>
368where
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 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
403impl<'ser, 'sig, 'b, W> ser::SerializeSeq for SeqSerializer<'ser, 'sig, 'b, W>
404where
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 let sig_parser = 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)]
431pub struct StructSerializer<'ser, 'sig, 'b, W> {
432 ser: &'b mut Serializer<'ser, 'sig, W>,
433 end_parens: u8,
435 container_depths: ContainerDepths,
437}
438
439impl<'ser, 'sig, 'b, W> StructSerializer<'ser, 'sig, 'b, W>
440where
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 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 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 self.ser.0.container_depths = self.container_depths;
542
543 Ok(())
544 }
545}
546
547#[doc(hidden)]
548pub enum StructSeqSerializer<'ser, 'sig, 'b, W> {
550 Struct(StructSerializer<'ser, 'sig, 'b, W>),
551 Seq(SeqSerializer<'ser, 'sig, 'b, W>),
552}
553
554macro_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}
601serialize_struct_anon_fields!(SerializeTuple serialize_element);
602serialize_struct_anon_fields!(SerializeTupleStruct serialize_field);
603serialize_struct_anon_fields!(SerializeTupleVariant serialize_field);
604
605impl<'ser, 'sig, 'b, W> ser::SerializeMap for SeqSerializer<'ser, 'sig, 'b, W>
606where
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 let sig_parser = self.ser.0.sig_parser.clone();
621 self.ser.0.sig_parser = sig_parser.clone();
622
623 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 let sig_parser = self.ser.0.sig_parser.clone();
639 self.ser.0.sig_parser = sig_parser.clone();
640
641 self.ser.0.sig_parser.skip_chars(2)?;
643
644 value.serialize(&mut *self.ser)?;
645 self.ser.0.sig_parser = sig_parser;
647
648 Ok(())
649 }
650
651 fn end(self) -> Result<()> {
652 self.end_seq()
653 }
654}
655
656macro_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}
703serialize_struct_named_fields!(SerializeStruct);
704serialize_struct_named_fields!(SerializeStructVariant);