1use std::{marker::PhantomData, mem::MaybeUninit};
2
3use ::serde::{de, de::Visitor, Deserialize, Deserializer};
4use faststr::FastStr;
5
6use super::{owned::OwnedLazyValue, value::LazyValue};
7use crate::lazyvalue::value::HasEsc;
8
9impl<'de: 'a, 'a> Deserialize<'de> for LazyValue<'a> {
10 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
11 where
12 D: Deserializer<'de>,
13 {
14 struct LazyValueVisitor<'a> {
15 _marker: PhantomData<&'a ()>,
16 }
17
18 impl<'de: 'a, 'a> Visitor<'de> for LazyValueVisitor<'a> {
19 type Value = LazyValue<'a>;
20
21 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
22 write!(formatter, "any valid JSON value")
23 }
24
25 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
27 where
28 E: de::Error,
29 {
30 Ok(LazyValue::new(FastStr::new(v).into(), HasEsc::Yes))
31 }
32
33 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
34 where
35 E: de::Error,
36 {
37 Ok(LazyValue::new(v.as_bytes().into(), HasEsc::None))
38 }
39 }
40
41 let visit = LazyValueVisitor {
42 _marker: PhantomData,
43 };
44 deserializer.deserialize_newtype_struct(super::TOKEN, visit)
45 }
46}
47
48impl<'de> Deserialize<'de> for OwnedLazyValue {
49 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50 where
51 D: Deserializer<'de>,
52 {
53 struct OwnedVisitor;
54
55 let visit = OwnedVisitor;
56
57 impl<'de> Visitor<'de> for OwnedVisitor {
58 type Value = OwnedLazyValue;
59
60 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 formatter.write_str("expect a valid json")
62 }
63
64 fn visit_bytes<E>(self, value_binary: &[u8]) -> std::result::Result<Self::Value, E>
65 where
66 E: de::Error,
67 {
68 unsafe {
70 assert!(
71 value_binary.len() == std::mem::size_of::<Self::Value>(),
72 "invalid value size {}",
73 value_binary.len()
74 );
75 let mut dom: MaybeUninit<Self::Value> = MaybeUninit::zeroed();
76 std::ptr::copy_nonoverlapping(
77 value_binary.as_ptr() as *const Self::Value,
78 dom.as_mut_ptr(),
79 1,
80 );
81 Ok(dom.assume_init())
82 }
83 }
84 }
85
86 deserializer.deserialize_newtype_struct(super::OWNED_LAZY_VALUE_TOKEN, visit)
87 }
88}