serde_fleece/
de.rs

1mod dict;
2mod seq;
3
4use std::{borrow::Borrow, marker::PhantomData, ptr::NonNull};
5
6use self::dict::DictAccess;
7use crate::{
8    de::{dict::EnumAccess, seq::ArrayAccess},
9    ffi::{
10        FLArray_Count, FLDict_Count, FLTrust, FLValueType, FLValue_AsArray, FLValue_AsBool,
11        FLValue_AsDict, FLValue_AsDouble, FLValue_AsFloat, FLValue_AsInt, FLValue_AsString,
12        FLValue_AsUnsigned, FLValue_FromData, FLValue_GetType, FLValue_IsDouble, FLValue_IsInteger,
13        FLValue_IsUnsigned, _FLDict, _FLValue,
14    },
15    Error,
16};
17use itoa::Integer;
18use serde::de::{self, IntoDeserializer};
19
20#[repr(transparent)]
21#[derive(Clone, Copy)]
22pub struct NonNullConst<T>(*const T);
23
24impl<T> NonNullConst<T> {
25    #[inline]
26    pub fn new(p: *const T) -> Option<Self> {
27        if !p.is_null() {
28            Some(Self(p))
29        } else {
30            None
31        }
32    }
33    /// # Safety
34    ///
35    /// the caller must guarantee that `ptr` is non-null.
36    #[inline]
37    pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
38        NonNullConst(ptr)
39    }
40    #[must_use]
41    #[inline]
42    pub const fn as_ptr(&self) -> *const T {
43        self.0
44    }
45    #[must_use]
46    #[inline]
47    pub const fn cast<U>(self) -> NonNullConst<U> {
48        // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
49        unsafe { NonNullConst::new_unchecked(self.as_ptr() as *mut U) }
50    }
51}
52
53impl<T> From<NonNull<T>> for NonNullConst<T> {
54    #[inline]
55    fn from(x: NonNull<T>) -> Self {
56        NonNullConst(x.as_ptr())
57    }
58}
59
60pub(crate) struct Deserializer<'de> {
61    pub value: NonNullConst<_FLValue>,
62    marker: PhantomData<&'de [u8]>,
63}
64
65impl<'de> Deserializer<'de> {
66    fn new(value: NonNullConst<_FLValue>) -> Self {
67        Self {
68            value,
69            marker: PhantomData,
70        }
71    }
72    fn from_slice(input: &'de [u8]) -> Result<Self, Error> {
73        let fl_val = unsafe { FLValue_FromData(input.into(), FLTrust::kFLUntrusted) };
74        let fl_val = NonNullConst::new(fl_val)
75            .ok_or_else(|| Error::InvalidFormat("untrusted data validation failed".into()))?;
76        Ok(Self::new(fl_val))
77    }
78
79    fn parse_signed<T: Integer + TryFrom<i64>>(&self) -> Result<T, Error> {
80        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
81        if ty == FLValueType::kFLNumber && unsafe { FLValue_IsInteger(self.value.as_ptr()) } {
82            let ret: T = unsafe { FLValue_AsInt(self.value.as_ptr()) }
83                .try_into()
84                .map_err(|_err| {
85                    Error::InvalidFormat("Can not shrink i64 to smaller integer".into())
86                })?;
87            Ok(ret)
88        } else {
89            Err(Error::InvalidFormat(
90                format!("Wrong data type: expect kFLNumber and integer, got {ty:?}").into(),
91            ))
92        }
93    }
94
95    fn parse_unsigned<T: Integer + TryFrom<u64>>(&self) -> Result<T, Error> {
96        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
97        if ty == FLValueType::kFLNumber && unsafe { FLValue_IsInteger(self.value.as_ptr()) } {
98            let ret: T = unsafe { FLValue_AsUnsigned(self.value.as_ptr()) }
99                .try_into()
100                .map_err(|_err| {
101                    Error::InvalidFormat("Can not shrink u64 to smaller unsigned integer".into())
102                })?;
103            Ok(ret)
104        } else {
105            Err(Error::InvalidFormat(
106                format!("Wrong data type: expect kFLNumber and integer, got {ty:?}").into(),
107            ))
108        }
109    }
110
111    fn parse_str(&self) -> Result<&'de str, Error> {
112        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
113        if ty == FLValueType::kFLString {
114            let s: &str = unsafe { FLValue_AsString(self.value.as_ptr()) }.try_into()?;
115            Ok(s)
116        } else {
117            Err(Error::InvalidFormat(
118                format!("Wrong data type: expect kFLString, got {ty:?}").into(),
119            ))
120        }
121    }
122}
123
124pub fn from_slice<'a, T>(s: &'a [u8]) -> Result<T, Error>
125where
126    T: de::Deserialize<'a>,
127{
128    let mut deserializer = Deserializer::from_slice(s)?;
129    T::deserialize(&mut deserializer)
130}
131
132pub fn from_fl_dict<'a, T, Dict>(dict: Dict) -> Result<T, Error>
133where
134    T: de::Deserialize<'a>,
135    Dict: Borrow<NonNullConst<_FLDict>>,
136{
137    let value: NonNullConst<_FLValue> = dict.borrow().cast();
138    let mut deserializer = Deserializer::<'a>::new(value);
139    T::deserialize(&mut deserializer)
140}
141
142pub fn from_fl_value<'a, T: de::Deserialize<'a>>(
143    value: NonNullConst<_FLValue>,
144) -> Result<T, Error> {
145    let mut deserializer = Deserializer::new(value);
146    T::deserialize(&mut deserializer)
147}
148
149impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
150    type Error = Error;
151
152    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
153    where
154        V: de::Visitor<'de>,
155    {
156        let fl_type = unsafe { FLValue_GetType(self.value.as_ptr()) };
157        match fl_type {
158            FLValueType::kFLUndefined => Err(Error::Unsupported(
159                "deserialize self described: `undefined` not supported",
160            )),
161            FLValueType::kFLNull => self.deserialize_unit(visitor),
162            FLValueType::kFLBoolean => self.deserialize_bool(visitor),
163            FLValueType::kFLNumber => {
164                if unsafe { FLValue_IsUnsigned(self.value.as_ptr()) } {
165                    self.deserialize_u64(visitor)
166                } else if unsafe { FLValue_IsInteger(self.value.as_ptr()) } {
167                    self.deserialize_i64(visitor)
168                } else if unsafe { FLValue_IsDouble(self.value.as_ptr()) } {
169                    self.deserialize_f64(visitor)
170                } else {
171                    self.deserialize_f32(visitor)
172                }
173            }
174            FLValueType::kFLString => self.deserialize_str(visitor),
175            FLValueType::kFLData => Err(Error::Unsupported(
176                "deserialize self described: `data` not supported",
177            )),
178            FLValueType::kFLArray => self.deserialize_seq(visitor),
179            FLValueType::kFLDict => self.deserialize_map(visitor),
180        }
181    }
182
183    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
184    where
185        V: de::Visitor<'de>,
186    {
187        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
188        if ty == FLValueType::kFLBoolean {
189            visitor.visit_bool(unsafe { FLValue_AsBool(self.value.as_ptr()) })
190        } else {
191            Err(Error::InvalidFormat(
192                format!("Wrong data type: expect kFLBoolean, got {ty:?}").into(),
193            ))
194        }
195    }
196
197    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
198    where
199        V: de::Visitor<'de>,
200    {
201        visitor.visit_i8(self.parse_signed()?)
202    }
203
204    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
205    where
206        V: de::Visitor<'de>,
207    {
208        visitor.visit_i16(self.parse_signed()?)
209    }
210
211    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
212    where
213        V: de::Visitor<'de>,
214    {
215        visitor.visit_i32(self.parse_signed()?)
216    }
217
218    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
219    where
220        V: de::Visitor<'de>,
221    {
222        visitor.visit_i64(self.parse_signed()?)
223    }
224
225    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
226    where
227        V: de::Visitor<'de>,
228    {
229        visitor.visit_u8(self.parse_unsigned()?)
230    }
231
232    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
233    where
234        V: de::Visitor<'de>,
235    {
236        visitor.visit_u16(self.parse_unsigned()?)
237    }
238
239    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
240    where
241        V: de::Visitor<'de>,
242    {
243        visitor.visit_u32(self.parse_unsigned()?)
244    }
245
246    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
247    where
248        V: de::Visitor<'de>,
249    {
250        visitor.visit_u64(self.parse_unsigned()?)
251    }
252
253    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
254    where
255        V: de::Visitor<'de>,
256    {
257        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
258        if ty == FLValueType::kFLNumber {
259            visitor.visit_f32(unsafe { FLValue_AsFloat(self.value.as_ptr()) })
260        } else {
261            Err(Error::InvalidFormat(
262                format!("Wrong data type: expect kFLNumber, got {ty:?}").into(),
263            ))
264        }
265    }
266
267    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
268    where
269        V: de::Visitor<'de>,
270    {
271        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
272        if ty == FLValueType::kFLNumber {
273            visitor.visit_f64(unsafe { FLValue_AsDouble(self.value.as_ptr()) })
274        } else {
275            Err(Error::InvalidFormat(
276                format!("Wrong data type: expect kFLNumber, got {ty:?}").into(),
277            ))
278        }
279    }
280
281    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
282    where
283        V: de::Visitor<'de>,
284    {
285        let s = self.parse_str()?;
286        let mut it = s.chars();
287        let ch = it.next();
288        let end = it.next();
289        if let (Some(ch), None) = (ch, end) {
290            visitor.visit_char(ch)
291        } else {
292            Err(Error::InvalidFormat(
293                format!("string({s}) should contain exactly one char").into(),
294            ))
295        }
296    }
297
298    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
299    where
300        V: de::Visitor<'de>,
301    {
302        visitor.visit_borrowed_str(self.parse_str()?)
303    }
304
305    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
306    where
307        V: de::Visitor<'de>,
308    {
309        self.deserialize_str(visitor)
310    }
311
312    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
313    where
314        V: de::Visitor<'de>,
315    {
316        Err(Error::Unsupported("deserialization of bytes not supported"))
317    }
318
319    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
320    where
321        V: de::Visitor<'de>,
322    {
323        Err(Error::Unsupported(
324            "deserialization of byte buf not supported",
325        ))
326    }
327
328    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
329    where
330        V: de::Visitor<'de>,
331    {
332        if unsafe { FLValue_GetType(self.value.as_ptr()) } != FLValueType::kFLNull {
333            visitor.visit_some(self)
334        } else {
335            visitor.visit_none()
336        }
337    }
338
339    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
340    where
341        V: de::Visitor<'de>,
342    {
343        if unsafe { FLValue_GetType(self.value.as_ptr()) } == FLValueType::kFLNull {
344            visitor.visit_unit()
345        } else {
346            Err(Error::InvalidFormat(
347                "Expect null in the place of unit".into(),
348            ))
349        }
350    }
351
352    fn deserialize_unit_struct<V>(
353        self,
354        _name: &'static str,
355        visitor: V,
356    ) -> Result<V::Value, Self::Error>
357    where
358        V: de::Visitor<'de>,
359    {
360        self.deserialize_unit(visitor)
361    }
362
363    fn deserialize_newtype_struct<V>(
364        self,
365        _name: &'static str,
366        visitor: V,
367    ) -> Result<V::Value, Self::Error>
368    where
369        V: de::Visitor<'de>,
370    {
371        visitor.visit_newtype_struct(self)
372    }
373
374    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
375    where
376        V: de::Visitor<'de>,
377    {
378        let ty = unsafe { FLValue_GetType(self.value.as_ptr()) };
379        if ty == FLValueType::kFLArray {
380            let arr = unsafe { FLValue_AsArray(self.value.as_ptr()) };
381            let arr = NonNullConst::new(arr)
382                .ok_or_else(|| Error::InvalidFormat("array is not array type".into()))?;
383            let n = unsafe { FLArray_Count(arr.as_ptr()) };
384            let n: usize = n.try_into().map_err(|err| {
385                Error::InvalidFormat(format!("Can not convert {n} to usize: {err}").into())
386            })?;
387            visitor.visit_seq(ArrayAccess::new(arr, n))
388        } else {
389            Err(Error::InvalidFormat(
390                format!("Wrong data type: expect kFLArray, got {ty:?}").into(),
391            ))
392        }
393    }
394
395    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
396    where
397        V: de::Visitor<'de>,
398    {
399        self.deserialize_seq(visitor)
400    }
401
402    fn deserialize_tuple_struct<V>(
403        self,
404        _name: &'static str,
405        _len: usize,
406        visitor: V,
407    ) -> Result<V::Value, Self::Error>
408    where
409        V: de::Visitor<'de>,
410    {
411        self.deserialize_seq(visitor)
412    }
413
414    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
415    where
416        V: de::Visitor<'de>,
417    {
418        let ftype = unsafe { FLValue_GetType(self.value.as_ptr()) };
419        if ftype != FLValueType::kFLDict {
420            return Err(Error::InvalidFormat(
421                format!("map has {ftype:?} type, should be kFLDict").into(),
422            ));
423        }
424
425        let dict = unsafe { FLValue_AsDict(self.value.as_ptr()) };
426        let dict = NonNullConst::new(dict)
427            .ok_or_else(|| Error::InvalidFormat("map: value to dict return null".into()))?;
428        let n = unsafe { FLDict_Count(dict.as_ptr()) };
429        let n: usize = n.try_into().map_err(|err| {
430            Error::InvalidFormat(format!("Can not convert {n} to usize: {err}").into())
431        })?;
432        visitor.visit_map(DictAccess::new(dict, n))
433    }
434
435    fn deserialize_struct<V>(
436        self,
437        name: &'static str,
438        _fields: &'static [&'static str],
439        visitor: V,
440    ) -> Result<V::Value, Self::Error>
441    where
442        V: de::Visitor<'de>,
443    {
444        let fv_type = unsafe { FLValue_GetType(self.value.as_ptr()) };
445        if fv_type != FLValueType::kFLDict {
446            return Err(Error::InvalidFormat(
447                format!("For struct {name} fleece data should be dict type, but got: {fv_type:?}")
448                    .into(),
449            ));
450        }
451
452        let dict = unsafe { FLValue_AsDict(self.value.as_ptr()) };
453        let dict = NonNullConst::new(dict).ok_or_else(|| {
454            Error::InvalidFormat(format!("struct {name} has not dict type (null)").into())
455        })?;
456        let dict_size = unsafe { FLDict_Count(dict.as_ptr()) };
457        let dict_size: usize = dict_size.try_into().map_err(|err| {
458            Error::InvalidFormat(format!("Can not convert {dict_size} to usize: {err}").into())
459        })?;
460
461        visitor.visit_map(DictAccess::new(dict, dict_size))
462    }
463
464    fn deserialize_enum<V>(
465        self,
466        name: &'static str,
467        _variants: &'static [&'static str],
468        visitor: V,
469    ) -> Result<V::Value, Self::Error>
470    where
471        V: de::Visitor<'de>,
472    {
473        let ftype = unsafe { FLValue_GetType(self.value.as_ptr()) };
474        match ftype {
475            FLValueType::kFLString => {
476                let s: &str = unsafe { FLValue_AsString(self.value.as_ptr()) }.try_into()?;
477                visitor.visit_enum(s.into_deserializer())
478            }
479            FLValueType::kFLDict => {
480                let dict = unsafe { FLValue_AsDict(self.value.as_ptr()) };
481                let dict = NonNullConst::new(dict).ok_or_else(|| {
482                    Error::InvalidFormat(format!("enum {name} has not dict type (null)").into())
483                })?;
484                visitor.visit_enum(EnumAccess::new(dict))
485            }
486            _ => Err(Error::InvalidFormat(
487                format!("Invalid type {ftype:?} for enum {name}").into(),
488            )),
489        }
490    }
491
492    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
493    where
494        V: de::Visitor<'de>,
495    {
496        self.deserialize_str(visitor)
497    }
498
499    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
500    where
501        V: de::Visitor<'de>,
502    {
503        // Called in case like there is unexpected key in dictionary, and we
504        // want to ignore value for this key. In our case we can do nothing.
505        // This is IgnoreAny visitor, and visit_unit do nothing.
506        visitor.visit_unit()
507    }
508}