1use std::num::NonZero;
2
3use crate::parser::{JsonParseErrorKind, JsonParseErrorWithContext, JsonParser};
4
5use facet_core::{Facet, Opaque, OpaqueUninit};
6use facet_poke::{PokeUninit, PokeValueUninit};
7use log::trace;
8
9pub 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
99fn 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: 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 PokeUninit::Scalar(pv) => {
150 trace!("Deserializing \x1b[1;36mscalar\x1b[0m");
151 fn aux<'input, 'mem>(
152 parser: &mut JsonParser<'input>,
153 pv: PokeValueUninit<'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 PokeUninit::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 PokeUninit::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 =
206 unsafe { PokeUninit::unchecked_new(item_data, item_shape) };
207
208 stack.push_front(StackItem::FinishList { pl });
209 stack.push_front(StackItem::AfterListItem { item: item_data });
210 stack.push_front(StackItem::Value { poke: item_poke });
211 } else {
212 stack.push_front(StackItem::FinishList { pl });
213 }
214 }
215 PokeUninit::Map(map_uninit) => {
216 trace!("Deserializing \x1b[1;36mhashmap\x1b[0m");
217 let first_key = parser.expect_object_start()?;
218
219 let pm = map_uninit.init(None).unwrap_or_else(|_| {
220 panic!("Failed to initialize map"); });
222
223 if let Some(key) = first_key {
224 let value_shape = pm.def().v;
225 let value_data =
226 OpaqueUninit::new(unsafe { std::alloc::alloc(value_shape.layout) });
227 let value_poke =
228 unsafe { PokeUninit::unchecked_new(value_data, value_shape) };
229
230 stack.push_front(StackItem::FinishMap { pm });
231 stack.push_front(StackItem::AfterMapValue {
232 key,
233 value: value_data,
234 });
235 stack.push_front(StackItem::Value { poke: value_poke });
236 } else {
237 stack.push_front(StackItem::FinishMap { pm });
238 }
239 }
240 PokeUninit::Enum(pe) => {
241 trace!("Deserializing \x1b[1;36menum\x1b[0m");
242 let variant_str = parser.parse_string()?;
243
244 let pe = pe.set_variant_by_name(&variant_str).map_err(|_| {
245 parser.make_error(JsonParseErrorKind::Custom(format!(
246 "Invalid enum variant: {}",
247 variant_str
248 )))
249 })?;
250
251 trace!("Finished deserializing \x1b[1;36menum\x1b[0m");
252 let opaque = pe.build_in_place();
253 result = Some(opaque);
254 }
255 _ => todo!("unsupported poke type"),
256 }
257 }
258 StackItem::StructField { key } => {
259 trace!("Processing struct key: \x1b[1;33m{}\x1b[0m", key);
260
261 let ps = match stack.front_mut().unwrap() {
262 StackItem::FinishStruct { ps } => ps,
263 _ => unreachable!(),
264 };
265
266 match ps.field_by_name(&key) {
267 Ok((index, field_poke)) => {
268 trace!("Found field, it's at index: \x1b[1;33m{index}\x1b[0m");
269
270 stack.push_front(StackItem::AfterStructField { index });
271
272 stack.push_front(StackItem::Value { poke: field_poke });
273 }
274 Err(_) => {
275 trace!("No field named \x1b[1;36m{}\x1b[0m", key);
276 return Err(parser.make_error(JsonParseErrorKind::UnknownField(key)));
277 }
278 }
279 }
280 StackItem::AfterStructField { index } => {
281 trace!("After processing struct field at index: \x1b[1;33m{index}\x1b[0m");
282
283 let ps = match stack.front_mut().unwrap() {
284 StackItem::FinishStruct { ps } => ps,
285 _ => unreachable!(),
286 };
287
288 unsafe {
289 ps.mark_initialized(index);
290 }
291
292 let next_key = parser.parse_object_key()?;
293 if let Some(next_key) = next_key {
294 stack.push_front(StackItem::StructField { key: next_key });
295 }
296 }
297 StackItem::FinishStruct { ps } => {
298 trace!("Finished deserializing \x1b[1;36mstruct\x1b[0m");
299
300 let opaque = ps.build_in_place();
301 result = Some(opaque);
302 }
303 StackItem::AfterListItem { item } => {
304 trace!("Processing array item at index");
305
306 let pl = match stack.front_mut().unwrap() {
307 StackItem::FinishList { pl } => pl,
308 _ => unreachable!(),
309 };
310 let item = unsafe { item.assume_init() };
311 unsafe {
312 pl.push(item);
313 }
314 unsafe { std::alloc::dealloc(item.as_mut_byte_ptr(), pl.def().t.layout) };
315
316 let has_next = parser.parse_array_element()?;
317 if let Some(true) = has_next {
318 let item_shape = pl.def().t;
319 let item_data =
320 OpaqueUninit::new(unsafe { std::alloc::alloc(item_shape.layout) });
321 let item_poke = unsafe { PokeUninit::unchecked_new(item_data, item_shape) };
322
323 stack.push_front(StackItem::AfterListItem { item: item_data });
324 stack.push_front(StackItem::Value { poke: item_poke });
325 }
326 }
327 StackItem::FinishList { pl } => {
328 trace!("Finished deserializing \x1b[1;36marray\x1b[0m");
329 let opaque = pl.build_in_place();
330 result = Some(opaque);
331 }
332 StackItem::AfterMapValue { mut key, value } => {
333 trace!("Processing hashmap key: \x1b[1;33m{}\x1b[0m", key);
334
335 let pm = match stack.front_mut().unwrap() {
336 StackItem::FinishMap { pm } => pm,
337 _ => unreachable!(),
338 };
339 let key_data = Opaque::new(&mut key);
340 let value = unsafe { value.assume_init() };
341 unsafe {
342 pm.insert(key_data, value);
343 }
344 core::mem::forget(key); unsafe { std::alloc::dealloc(value.as_mut_byte_ptr(), pm.def().v.layout) };
346
347 let next_key = parser.parse_object_key()?;
348 if let Some(next_key) = next_key {
349 let value_shape = pm.def().v;
350 let value_data =
351 OpaqueUninit::new(unsafe { std::alloc::alloc(value_shape.layout) });
352 let value_poke = unsafe { PokeUninit::unchecked_new(value_data, value_shape) };
353
354 stack.push_front(StackItem::AfterMapValue {
355 key: next_key,
356 value: value_data,
357 });
358 stack.push_front(StackItem::Value { poke: value_poke });
359 }
360 }
361 StackItem::FinishMap { pm } => {
362 trace!("Finished deserializing \x1b[1;36mhashmap\x1b[0m");
363 let opaque = pm.build_in_place();
364 result = Some(opaque);
365 }
366 }
367 }
368
369 result.ok_or_else(|| {
370 parser.make_error(JsonParseErrorKind::Custom(
371 "Unexpected end of input".to_string(),
372 ))
373 })
374}