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