zvariant/
de.rs

1use serde::de::{self, DeserializeSeed, VariantAccess, Visitor};
2use static_assertions::assert_impl_all;
3
4use std::{marker::PhantomData, str};
5
6#[cfg(unix)]
7use std::os::fd::{AsFd, AsRawFd};
8
9#[cfg(feature = "gvariant")]
10use crate::gvariant::Deserializer as GVDeserializer;
11use crate::{
12    container_depths::ContainerDepths, dbus::Deserializer as DBusDeserializer, serialized::Context,
13    signature_parser::SignatureParser, utils::*, Basic, Error, ObjectPath, Result, Signature,
14};
15
16#[cfg(unix)]
17use crate::Fd;
18
19/// Our deserialization implementation.
20#[derive(Debug)]
21pub(crate) struct DeserializerCommon<'de, 'sig, 'f, F> {
22    pub(crate) ctxt: Context,
23    pub(crate) bytes: &'de [u8],
24
25    #[cfg(unix)]
26    pub(crate) fds: Option<&'f [F]>,
27    #[cfg(not(unix))]
28    pub(crate) fds: PhantomData<&'f F>,
29
30    pub(crate) pos: usize,
31
32    pub(crate) sig_parser: SignatureParser<'sig>,
33
34    pub(crate) container_depths: ContainerDepths,
35}
36
37/// Our deserialization implementation.
38///
39/// Using this deserializer involves an redirection to the actual deserializer. It's best
40/// to use the serialization functions, e.g [`crate::to_bytes`] or specific serializers,
41/// [`crate::dbus::Deserializer`] or [`crate::zvariant::Deserializer`].
42pub(crate) enum Deserializer<'ser, 'sig, 'f, F> {
43    DBus(DBusDeserializer<'ser, 'sig, 'f, F>),
44    #[cfg(feature = "gvariant")]
45    GVariant(GVDeserializer<'ser, 'sig, 'f, F>),
46}
47
48assert_impl_all!(Deserializer<'_, '_, '_, ()>: Send, Sync, Unpin);
49
50#[cfg(unix)]
51impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F>
52where
53    F: AsFd,
54{
55    pub fn get_fd(&self, idx: u32) -> Result<i32> {
56        self.fds
57            .and_then(|fds| fds.get(idx as usize).map(|fd| fd.as_fd().as_raw_fd()))
58            .ok_or(Error::UnknownFd)
59    }
60}
61
62impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F> {
63    pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> {
64        let padding = padding_for_n_bytes(self.abs_pos(), alignment);
65        if padding > 0 {
66            if self.pos + padding > self.bytes.len() {
67                return Err(serde::de::Error::invalid_length(
68                    self.bytes.len(),
69                    &format!(">= {}", self.pos + padding).as_str(),
70                ));
71            }
72
73            for i in 0..padding {
74                let byte = self.bytes[self.pos + i];
75                if byte != 0 {
76                    return Err(Error::PaddingNot0(byte));
77                }
78            }
79            self.pos += padding;
80        }
81
82        Ok(padding)
83    }
84
85    pub fn prep_deserialize_basic<T>(&mut self) -> Result<()>
86    where
87        T: Basic,
88    {
89        self.sig_parser.skip_char()?;
90        self.parse_padding(T::alignment(self.ctxt.format()))?;
91
92        Ok(())
93    }
94
95    pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> {
96        if self.pos + len > self.bytes.len() {
97            return Err(serde::de::Error::invalid_length(
98                self.bytes.len(),
99                &format!(">= {}", self.pos + len).as_str(),
100            ));
101        }
102
103        let slice = &self.bytes[self.pos..self.pos + len];
104        self.pos += len;
105
106        Ok(slice)
107    }
108
109    pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]>
110    where
111        T: Basic,
112    {
113        self.prep_deserialize_basic::<T>()?;
114
115        self.next_slice(T::alignment(self.ctxt.format()))
116    }
117
118    pub fn abs_pos(&self) -> usize {
119        self.ctxt.position() + self.pos
120    }
121}
122
123macro_rules! deserialize_method {
124    ($method:ident($($arg:ident: $type:ty),*)) => {
125        #[inline]
126        fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value>
127        where
128            V: Visitor<'de>,
129        {
130            match self {
131                #[cfg(feature = "gvariant")]
132                Deserializer::GVariant(de) => {
133                    de.$method($($arg,)* visitor)
134                }
135                Deserializer::DBus(de) => {
136                    de.$method($($arg,)* visitor)
137                }
138            }
139        }
140    }
141}
142
143impl<'de, 'd, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> de::Deserializer<'de>
144    for &'d mut Deserializer<'de, 'sig, 'f, F>
145{
146    type Error = Error;
147
148    deserialize_method!(deserialize_any());
149    deserialize_method!(deserialize_bool());
150    deserialize_method!(deserialize_i8());
151    deserialize_method!(deserialize_i16());
152    deserialize_method!(deserialize_i32());
153    deserialize_method!(deserialize_i64());
154    deserialize_method!(deserialize_u8());
155    deserialize_method!(deserialize_u16());
156    deserialize_method!(deserialize_u32());
157    deserialize_method!(deserialize_u64());
158    deserialize_method!(deserialize_f32());
159    deserialize_method!(deserialize_f64());
160    deserialize_method!(deserialize_char());
161    deserialize_method!(deserialize_str());
162    deserialize_method!(deserialize_string());
163    deserialize_method!(deserialize_bytes());
164    deserialize_method!(deserialize_byte_buf());
165    deserialize_method!(deserialize_option());
166    deserialize_method!(deserialize_unit());
167    deserialize_method!(deserialize_unit_struct(n: &'static str));
168    deserialize_method!(deserialize_newtype_struct(n: &'static str));
169    deserialize_method!(deserialize_seq());
170    deserialize_method!(deserialize_map());
171    deserialize_method!(deserialize_tuple(n: usize));
172    deserialize_method!(deserialize_tuple_struct(n: &'static str, l: usize));
173    deserialize_method!(deserialize_struct(
174        n: &'static str,
175        f: &'static [&'static str]
176    ));
177    deserialize_method!(deserialize_enum(
178        n: &'static str,
179        f: &'static [&'static str]
180    ));
181    deserialize_method!(deserialize_identifier());
182    deserialize_method!(deserialize_ignored_any());
183
184    fn is_human_readable(&self) -> bool {
185        false
186    }
187}
188
189#[derive(Debug)]
190pub(crate) enum ValueParseStage {
191    Signature,
192    Value,
193    Done,
194}
195
196pub(crate) fn deserialize_any<'de, 'sig, 'f, D, V>(
197    de: D,
198    next_char: char,
199    visitor: V,
200) -> Result<V::Value>
201where
202    D: de::Deserializer<'de, Error = Error>,
203    V: Visitor<'de>,
204{
205    match next_char {
206        u8::SIGNATURE_CHAR => de.deserialize_u8(visitor),
207        bool::SIGNATURE_CHAR => de.deserialize_bool(visitor),
208        i16::SIGNATURE_CHAR => de.deserialize_i16(visitor),
209        u16::SIGNATURE_CHAR => de.deserialize_u16(visitor),
210        i32::SIGNATURE_CHAR => de.deserialize_i32(visitor),
211        #[cfg(unix)]
212        Fd::SIGNATURE_CHAR => de.deserialize_i32(visitor),
213        u32::SIGNATURE_CHAR => de.deserialize_u32(visitor),
214        i64::SIGNATURE_CHAR => de.deserialize_i64(visitor),
215        u64::SIGNATURE_CHAR => de.deserialize_u64(visitor),
216        f64::SIGNATURE_CHAR => de.deserialize_f64(visitor),
217        <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR | Signature::SIGNATURE_CHAR => {
218            de.deserialize_str(visitor)
219        }
220        VARIANT_SIGNATURE_CHAR => de.deserialize_seq(visitor),
221        ARRAY_SIGNATURE_CHAR => de.deserialize_seq(visitor),
222        STRUCT_SIG_START_CHAR => de.deserialize_seq(visitor),
223        #[cfg(feature = "gvariant")]
224        MAYBE_SIGNATURE_CHAR => de.deserialize_option(visitor),
225        c => Err(de::Error::invalid_value(
226            de::Unexpected::Char(c),
227            &"a valid signature character",
228        )),
229    }
230}
231
232// Enum handling is very generic so it can be here and specific deserializers can use this.
233pub(crate) struct Enum<D, F> {
234    pub(crate) de: D,
235    pub(crate) name: &'static str,
236    pub(crate) _phantom: PhantomData<F>,
237}
238
239impl<'de, D, F> VariantAccess<'de> for Enum<D, F>
240where
241    D: de::Deserializer<'de, Error = Error>,
242{
243    type Error = Error;
244
245    fn unit_variant(self) -> std::result::Result<(), Self::Error> {
246        Ok(())
247    }
248
249    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
250    where
251        T: DeserializeSeed<'de>,
252    {
253        seed.deserialize(self.de)
254    }
255
256    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
257    where
258        V: Visitor<'de>,
259    {
260        de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor)
261    }
262
263    fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
264    where
265        V: Visitor<'de>,
266    {
267        de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor)
268    }
269}