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