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