1use std::num::NonZero;
2
3use crate::parser::{JsonParseErrorKind, JsonParseErrorWithContext, JsonParser};
4
5use facet_core::{Facet, Opaque, OpaqueUninit};
6use facet_reflect::{PokeList, PokeMap, PokeStruct, PokeUninit, PokeValueUninit};
7use log::trace;
8
9pub fn from_str<T: Facet>(json: &str) -> Result<T, JsonParseErrorWithContext<'_>> {
31 let (poke, _guard) = PokeUninit::alloc::<T>();
32 let opaque = from_str_opaque(poke, json)?;
33 Ok(unsafe { opaque.read::<T>() })
34}
35
36pub fn from_str_opaque<'input, 'mem>(
38 poke: PokeUninit<'mem>,
39 json: &'input str,
40) -> Result<Opaque<'mem>, JsonParseErrorWithContext<'input>> {
41 trace!("Starting JSON deserialization");
42 let mut parser = JsonParser::new(json);
43 deserialize_value(&mut parser, poke)
44}
45
46macro_rules! int {
47 ($parser:expr, $parsed:expr, $pv:expr, $type:ty) => {
48 if $pv.shape().is_type::<$type>() {
49 let n = <$type>::try_from($parsed?).map_err(|e| {
50 $parser.make_error(JsonParseErrorKind::Custom(format!(
51 "Invalid value for {}: {e}",
52 stringify!($type)
53 )))
54 })?;
55 return Ok($pv.put(n));
56 }
57
58 if $pv.shape().is_type::<NonZero<$type>>() {
59 let n = <$type>::try_from($parsed?).map_err(|e| {
60 $parser.make_error(JsonParseErrorKind::Custom(format!(
61 "Invalid value for core::num::NonZero<{}>: {e}",
62 stringify!($type)
63 )))
64 })?;
65 let n = NonZero::new(n).ok_or_else(|| {
66 $parser.make_error(JsonParseErrorKind::Custom(format!(
67 "Can't deserialize zero to core::num::NonZero<{}>",
68 stringify!($type)
69 )))
70 })?;
71
72 return Ok($pv.put(n));
73 }
74 };
75}
76
77macro_rules! unsigneds {
78 ($parser:expr, $pv:expr, $type:ty, $($types:ty),*) => {
79 int!($parser, $parser.parse_u64(), $pv, $type);
80 unsigneds!($parser, $pv, $($types),*);
81 };
82 ($parser:expr, $pv:expr, $type:ty) => {
83 int!($parser, $parser.parse_u64(), $pv, $type);
84 };
85}
86
87macro_rules! signeds {
88 ($parser:expr, $pv:expr, $type:ty, $($types:ty),*) => {
89 int!($parser, $parser.parse_i64(), $pv, $type);
90 signeds!($parser, $pv, $($types),*);
91 };
92 ($parser:expr, $pv:expr, $type:ty) => {
93 int!($parser, $parser.parse_i64(), $pv, $type);
94 };
95}
96
97pub(crate) fn deserialize_value<'input, 'mem>(
103 parser: &mut JsonParser<'input>,
104 root_poke: PokeUninit<'mem>,
105) -> Result<Opaque<'mem>, JsonParseErrorWithContext<'input>> {
106 use std::collections::VecDeque;
107
108 enum StackItem<'mem> {
109 Value {
110 poke: PokeUninit<'mem>,
111 },
112 FinishStruct {
113 ps: PokeStruct<'mem>,
114 },
115 StructField {
116 key: String,
117 },
118 AfterStructField {
119 index: usize,
120 },
121 FinishList {
122 pl: PokeList<'mem>,
123 },
124 AfterListItem {
125 item: OpaqueUninit<'mem>,
126 },
127 FinishMap {
128 pm: PokeMap<'mem>,
129 },
130 AfterMapValue {
131 key: String,
132 value: OpaqueUninit<'mem>,
133 },
134 }
135
136 let mut result = None;
137 let mut stack = VecDeque::new();
138 stack.push_back(StackItem::Value { poke: root_poke });
139
140 while let Some(item) = stack.pop_front() {
141 match item {
142 StackItem::Value { poke } => {
143 let shape = poke.shape();
144 trace!("Deserializing {shape}");
145
146 match poke {
147 PokeUninit::Scalar(pv) => {
148 trace!("Deserializing \x1b[1;36mscalar\x1b[0m");
149 fn aux<'input, 'mem>(
150 parser: &mut JsonParser<'input>,
151 pv: PokeValueUninit<'mem>,
152 ) -> Result<Opaque<'mem>, JsonParseErrorWithContext<'input>>
153 {
154 if pv.shape().is_type::<String>() {
155 let s = parser.parse_string()?;
156 let data = pv.put(s);
157 return Ok(data);
158 }
159 if pv.shape().is_type::<bool>() {
160 let b = parser.parse_bool()?;
161 return Ok(pv.put(b));
162 }
163 if pv.shape().is_type::<f32>() {
164 let n = parser.parse_f64()? as f32;
165 return Ok(pv.put(n));
166 }
167 if pv.shape().is_type::<f64>() {
168 let n = parser.parse_f64()?;
169 return Ok(pv.put(n));
170 }
171
172 unsigneds!(parser, pv, u8, u16, u32, u64, u128, usize);
173 signeds!(parser, pv, i8, i16, i32, i64, i128, isize);
174
175 panic!("Unknown scalar shape: {}", pv.shape());
176 }
177
178 result = Some(aux(parser, pv)?);
179 }
180 PokeUninit::Struct(ps) => {
181 trace!("Deserializing \x1b[1;36mstruct\x1b[0m");
182 stack.push_front(StackItem::FinishStruct { ps });
183
184 let first_key = parser.expect_object_start()?;
185 if let Some(key) = first_key {
186 stack.push_front(StackItem::StructField { key });
187 }
188 }
189 PokeUninit::List(list_uninit) => {
190 trace!("Deserializing \x1b[1;36marray\x1b[0m");
191 parser.expect_array_start()?;
192
193 let pl = list_uninit.init(None).unwrap_or_else(|_| {
194 panic!("Failed to initialize list");
195 });
196
197 let has_element = parser.parse_array_element()?;
198
199 if let Some(true) = has_element {
200 let item_shape = pl.def().t;
201 let item_data =
202 OpaqueUninit::new(unsafe { std::alloc::alloc(item_shape.layout) });
203 let item_poke =
204 unsafe { PokeUninit::unchecked_new(item_data, item_shape) };
205
206 stack.push_front(StackItem::FinishList { pl });
207 stack.push_front(StackItem::AfterListItem { item: item_data });
208 stack.push_front(StackItem::Value { poke: item_poke });
209 } else {
210 stack.push_front(StackItem::FinishList { pl });
211 }
212 }
213 PokeUninit::Map(map_uninit) => {
214 trace!("Deserializing \x1b[1;36mhashmap\x1b[0m");
215 let first_key = parser.expect_object_start()?;
216
217 let pm = map_uninit.init(None).unwrap_or_else(|_| {
218 panic!("Failed to initialize map"); });
220
221 if let Some(key) = first_key {
222 let value_shape = pm.def().v;
223 let value_data =
224 OpaqueUninit::new(unsafe { std::alloc::alloc(value_shape.layout) });
225 let value_poke =
226 unsafe { PokeUninit::unchecked_new(value_data, value_shape) };
227
228 stack.push_front(StackItem::FinishMap { pm });
229 stack.push_front(StackItem::AfterMapValue {
230 key,
231 value: value_data,
232 });
233 stack.push_front(StackItem::Value { poke: value_poke });
234 } else {
235 stack.push_front(StackItem::FinishMap { pm });
236 }
237 }
238 PokeUninit::Enum(pe) => {
239 trace!("Deserializing \x1b[1;36menum\x1b[0m");
240 let variant_str = parser.parse_string()?;
241
242 let pe = pe.set_variant_by_name(&variant_str).map_err(|_| {
243 parser.make_error(JsonParseErrorKind::Custom(format!(
244 "Invalid enum variant: {}",
245 variant_str
246 )))
247 })?;
248
249 trace!("Finished deserializing \x1b[1;36menum\x1b[0m");
250 let opaque = pe.build_in_place();
251 result = Some(opaque);
252 }
253 _ => todo!("unsupported poke type"),
254 }
255 }
256 StackItem::StructField { key } => {
257 trace!("Processing struct key: \x1b[1;33m{}\x1b[0m", key);
258
259 let ps = match stack.front_mut().unwrap() {
260 StackItem::FinishStruct { ps } => ps,
261 _ => unreachable!(),
262 };
263
264 match ps.field_by_name(&key) {
265 Ok((index, field_poke)) => {
266 trace!("Found field, it's at index: \x1b[1;33m{index}\x1b[0m");
267
268 stack.push_front(StackItem::AfterStructField { index });
269
270 stack.push_front(StackItem::Value { poke: field_poke });
271 }
272 Err(_) => {
273 trace!("No field named \x1b[1;36m{}\x1b[0m", key);
274 return Err(parser.make_error(JsonParseErrorKind::UnknownField(key)));
275 }
276 }
277 }
278 StackItem::AfterStructField { index } => {
279 trace!("After processing struct field at index: \x1b[1;33m{index}\x1b[0m");
280
281 let ps = match stack.front_mut().unwrap() {
282 StackItem::FinishStruct { ps } => ps,
283 _ => unreachable!(),
284 };
285
286 unsafe {
287 ps.mark_initialized(index);
288 }
289
290 let next_key = parser.parse_object_key()?;
291 if let Some(next_key) = next_key {
292 stack.push_front(StackItem::StructField { key: next_key });
293 }
294 }
295 StackItem::FinishStruct { ps } => {
296 trace!("Finished deserializing \x1b[1;36mstruct\x1b[0m");
297
298 let opaque = ps.build_in_place();
299 result = Some(opaque);
300 }
301 StackItem::AfterListItem { item } => {
302 trace!("Processing array item at index");
303
304 let pl = match stack.front_mut().unwrap() {
305 StackItem::FinishList { pl } => pl,
306 _ => unreachable!(),
307 };
308 let item = unsafe { item.assume_init() };
309 unsafe {
310 pl.push(item);
311 }
312 unsafe { std::alloc::dealloc(item.as_mut_byte_ptr(), pl.def().t.layout) };
313
314 let has_next = parser.parse_array_element()?;
315 if let Some(true) = has_next {
316 let item_shape = pl.def().t;
317 let item_data =
318 OpaqueUninit::new(unsafe { std::alloc::alloc(item_shape.layout) });
319 let item_poke = unsafe { PokeUninit::unchecked_new(item_data, item_shape) };
320
321 stack.push_front(StackItem::AfterListItem { item: item_data });
322 stack.push_front(StackItem::Value { poke: item_poke });
323 }
324 }
325 StackItem::FinishList { pl } => {
326 trace!("Finished deserializing \x1b[1;36marray\x1b[0m");
327 let opaque = pl.build_in_place();
328 result = Some(opaque);
329 }
330 StackItem::AfterMapValue { mut key, value } => {
331 trace!("Processing hashmap key: \x1b[1;33m{}\x1b[0m", key);
332
333 let pm = match stack.front_mut().unwrap() {
334 StackItem::FinishMap { pm } => pm,
335 _ => unreachable!(),
336 };
337 let key_data = Opaque::new(&mut key);
338 let value = unsafe { value.assume_init() };
339 unsafe {
340 pm.insert(key_data, value);
341 }
342 core::mem::forget(key); unsafe { std::alloc::dealloc(value.as_mut_byte_ptr(), pm.def().v.layout) };
344
345 let next_key = parser.parse_object_key()?;
346 if let Some(next_key) = next_key {
347 let value_shape = pm.def().v;
348 let value_data =
349 OpaqueUninit::new(unsafe { std::alloc::alloc(value_shape.layout) });
350 let value_poke = unsafe { PokeUninit::unchecked_new(value_data, value_shape) };
351
352 stack.push_front(StackItem::AfterMapValue {
353 key: next_key,
354 value: value_data,
355 });
356 stack.push_front(StackItem::Value { poke: value_poke });
357 }
358 }
359 StackItem::FinishMap { pm } => {
360 trace!("Finished deserializing \x1b[1;36mhashmap\x1b[0m");
361 let opaque = pm.build_in_place();
362 result = Some(opaque);
363 }
364 }
365 }
366
367 result.ok_or_else(|| {
368 parser.make_error(JsonParseErrorKind::Custom(
369 "Unexpected end of input".to_string(),
370 ))
371 })
372}