zvariant/dbus/
ser.rs

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
19/// Our D-Bus serialization implementation.
20pub(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    /// 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
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    // 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)]
356pub 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
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        // 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
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        // We want to keep parsing the same signature repeatedly for each element so we use a
415        // disposable clone.
416        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    // 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
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        // 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.
549pub 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        // 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
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);