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 #[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 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 visitor.visit_unit()
507 }
508}