1use serde::de::{self, DeserializeSeed, VariantAccess, Visitor};
2
3use std::{marker::PhantomData, str};
4
5#[cfg(unix)]
6use std::os::fd::{AsFd, AsRawFd};
7
8#[cfg(feature = "gvariant")]
9#[allow(deprecated)]
10use crate::gvariant::Deserializer as GVDeserializer;
11use crate::{
12 Basic, Error, Result, Signature, container_depths::ContainerDepths,
13 dbus::Deserializer as DBusDeserializer, serialized::Context, utils::*,
14};
15
16#[derive(Debug)]
18pub(crate) struct DeserializerCommon<'de, 'sig, 'f, F> {
19 pub(crate) ctxt: Context,
20 pub(crate) bytes: &'de [u8],
21
22 #[cfg(unix)]
23 pub(crate) fds: Option<&'f [F]>,
24 #[cfg(not(unix))]
25 pub(crate) fds: PhantomData<&'f F>,
26
27 pub(crate) pos: usize,
28
29 pub(crate) signature: &'sig Signature,
30
31 pub(crate) container_depths: ContainerDepths,
32}
33
34pub(crate) enum Deserializer<'ser, 'sig, 'f, F> {
40 DBus(DBusDeserializer<'ser, 'sig, 'f, F>),
41 #[cfg(feature = "gvariant")]
42 #[allow(deprecated)]
43 GVariant(GVDeserializer<'ser, 'sig, 'f, F>),
44}
45
46#[cfg(unix)]
47impl<F> DeserializerCommon<'_, '_, '_, F>
48where
49 F: AsFd,
50{
51 pub fn get_fd(&self, idx: u32) -> Result<i32> {
52 self.fds
53 .and_then(|fds| fds.get(idx as usize).map(|fd| fd.as_fd().as_raw_fd()))
54 .ok_or(Error::UnknownFd)
55 }
56}
57
58impl<'de, F> DeserializerCommon<'de, '_, '_, F> {
59 pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> {
60 let padding = padding_for_n_bytes(self.abs_pos(), alignment);
61 if padding > 0 {
62 if self.pos + padding > self.bytes.len() {
63 return Err(serde::de::Error::invalid_length(
64 self.bytes.len(),
65 &format!(">= {}", self.pos + padding).as_str(),
66 ));
67 }
68
69 for i in 0..padding {
70 let byte = self.bytes[self.pos + i];
71 if byte != 0 {
72 return Err(Error::PaddingNot0(byte));
73 }
74 }
75 self.pos += padding;
76 }
77
78 Ok(padding)
79 }
80
81 pub fn prep_deserialize_basic<T>(&mut self) -> Result<()>
82 where
83 T: Basic,
84 {
85 self.parse_padding(T::alignment(self.ctxt.format()))?;
86
87 Ok(())
88 }
89
90 pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> {
91 if self.pos + len > self.bytes.len() {
92 return Err(serde::de::Error::invalid_length(
93 self.bytes.len(),
94 &format!(">= {}", self.pos + len).as_str(),
95 ));
96 }
97
98 let slice = &self.bytes[self.pos..self.pos + len];
99 self.pos += len;
100
101 Ok(slice)
102 }
103
104 pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]>
105 where
106 T: Basic,
107 {
108 self.prep_deserialize_basic::<T>()?;
109
110 self.next_slice(T::alignment(self.ctxt.format()))
111 }
112
113 pub fn abs_pos(&self) -> usize {
114 self.ctxt.position() + self.pos
115 }
116}
117
118macro_rules! deserialize_method {
119 ($method:ident($($arg:ident: $type:ty),*)) => {
120 #[inline]
121 fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value>
122 where
123 V: Visitor<'de>,
124 {
125 match self {
126 #[cfg(feature = "gvariant")]
127 Deserializer::GVariant(de) => {
128 de.$method($($arg,)* visitor)
129 }
130 Deserializer::DBus(de) => {
131 de.$method($($arg,)* visitor)
132 }
133 }
134 }
135 }
136}
137
138impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> de::Deserializer<'de>
139 for &mut Deserializer<'de, '_, '_, F>
140{
141 type Error = Error;
142
143 deserialize_method!(deserialize_any());
144 deserialize_method!(deserialize_bool());
145 deserialize_method!(deserialize_i8());
146 deserialize_method!(deserialize_i16());
147 deserialize_method!(deserialize_i32());
148 deserialize_method!(deserialize_i64());
149 deserialize_method!(deserialize_u8());
150 deserialize_method!(deserialize_u16());
151 deserialize_method!(deserialize_u32());
152 deserialize_method!(deserialize_u64());
153 deserialize_method!(deserialize_f32());
154 deserialize_method!(deserialize_f64());
155 deserialize_method!(deserialize_char());
156 deserialize_method!(deserialize_str());
157 deserialize_method!(deserialize_string());
158 deserialize_method!(deserialize_bytes());
159 deserialize_method!(deserialize_byte_buf());
160 deserialize_method!(deserialize_option());
161 deserialize_method!(deserialize_unit());
162 deserialize_method! { deserialize_unit_struct(n: &'static str) }
165 deserialize_method! { deserialize_newtype_struct(n: &'static str) }
166 deserialize_method!(deserialize_seq());
167 deserialize_method!(deserialize_map());
168 deserialize_method! { deserialize_tuple(n: usize) }
169 deserialize_method! { deserialize_tuple_struct(n: &'static str, l: usize) }
170 deserialize_method! { deserialize_struct(n: &'static str, f: &'static [&'static str]) }
171 deserialize_method! { deserialize_enum(n: &'static str, f: &'static [&'static str]) }
172 deserialize_method!(deserialize_identifier());
173 deserialize_method!(deserialize_ignored_any());
174
175 fn is_human_readable(&self) -> bool {
176 false
177 }
178}
179
180#[derive(Debug)]
181pub(crate) enum ValueParseStage {
182 Signature,
183 Value,
184 Done,
185}
186
187pub(crate) fn deserialize_any<'de, 'f, D, V>(
188 de: D,
189 signature: &Signature,
190 visitor: V,
191) -> Result<V::Value>
192where
193 D: de::Deserializer<'de, Error = Error>,
194 V: Visitor<'de>,
195{
196 match signature {
197 Signature::Unit => de.deserialize_unit(visitor),
198 Signature::U8 => de.deserialize_u8(visitor),
199 Signature::Bool => de.deserialize_bool(visitor),
200 Signature::I16 => de.deserialize_i16(visitor),
201 Signature::U16 => de.deserialize_u16(visitor),
202 Signature::I32 => de.deserialize_i32(visitor),
203 #[cfg(unix)]
204 Signature::Fd => de.deserialize_i32(visitor),
205 Signature::U32 => de.deserialize_u32(visitor),
206 Signature::I64 => de.deserialize_i64(visitor),
207 Signature::U64 => de.deserialize_u64(visitor),
208 Signature::F64 => de.deserialize_f64(visitor),
209 Signature::Str | Signature::ObjectPath | Signature::Signature => {
210 de.deserialize_str(visitor)
211 }
212 Signature::Variant => de.deserialize_seq(visitor),
213 Signature::Array(_) => de.deserialize_seq(visitor),
214 Signature::Dict { .. } => de.deserialize_map(visitor),
215 Signature::Structure { .. } => de.deserialize_seq(visitor),
216 #[cfg(feature = "gvariant")]
217 Signature::Maybe(_) => de.deserialize_option(visitor),
218 #[cfg(not(feature = "gvariant"))]
227 #[allow(unreachable_patterns)]
228 _ => Err(Error::SignatureMismatch(
229 signature.clone(),
230 "GVariant `Maybe` support has moved to the `zgvariant` crate; enable `zvariant`'s \
231 deprecated `gvariant` feature only for legacy compatibility"
232 .to_string(),
233 )),
234 }
235}
236
237pub(crate) struct Enum<D, F> {
239 pub(crate) de: D,
240 pub(crate) name: &'static str,
241 pub(crate) _phantom: PhantomData<F>,
242}
243
244impl<'de, D, F> VariantAccess<'de> for Enum<D, F>
245where
246 D: de::Deserializer<'de, Error = Error>,
247{
248 type Error = Error;
249
250 fn unit_variant(self) -> std::result::Result<(), Self::Error> {
251 Ok(())
252 }
253
254 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
255 where
256 T: DeserializeSeed<'de>,
257 {
258 seed.deserialize(self.de)
259 }
260
261 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
262 where
263 V: Visitor<'de>,
264 {
265 de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor)
266 }
267
268 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
269 where
270 V: Visitor<'de>,
271 {
272 de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor)
273 }
274}