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