1use 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>();
33
34 let opaque = from_str_opaque(poke, json)?;
36
37 let result = unsafe { opaque.read::<T>() };
39
40 Ok(result)
41}
42
43pub fn from_str_opaque<'input, 'mem>(
45 poke: Poke<'mem>,
46 json: &'input str,
47) -> Result<Opaque<'mem>, JsonParseErrorWithContext<'input>> {
48 trace!("Starting JSON deserialization");
49 let mut parser = JsonParser::new(json);
50 deserialize_value(&mut parser, poke)
51}
52
53fn deserialize_value<'input, 'mem>(
54 parser: &mut JsonParser<'input>,
55 poke: Poke<'mem>,
56) -> Result<Opaque<'mem>, JsonParseErrorWithContext<'input>> {
57 let shape = poke.shape();
58 trace!("Deserializing {:?}", shape);
59
60 let opaque = match poke {
61 Poke::Scalar(pv) => {
62 trace!("Deserializing \x1b[1;36mscalar\x1b[0m");
63 if pv.shape().is_type::<String>() {
64 let s = parser.parse_string()?;
65 let data = unsafe { pv.put(OpaqueConst::from_ref(&s)) };
66 std::mem::forget(s);
67 data
68 } else if pv.shape().is_type::<u64>() {
69 let n = parser.parse_u64()?;
70 unsafe { pv.put(OpaqueConst::from_ref(&n)) }
71 } else {
72 panic!("Unknown scalar shape: {}", pv.shape());
73 }
74 }
75 Poke::Struct(mut ps) => {
76 trace!("Deserializing \x1b[1;36mstruct\x1b[0m");
77
78 let mut first = true;
79 while let Some(key) = if first {
80 first = false;
81 parser.expect_object_start()?
82 } else {
83 parser.parse_object_key()?
84 } {
85 trace!("Processing struct key: \x1b[1;33m{}\x1b[0m", key);
86 let index = match ps.field_by_name(&key) {
87 Ok((index, field_poke)) => {
88 deserialize_value(parser, field_poke)?;
89 index
90 }
91 Err(_) => {
92 return Err(parser.make_error(JsonParseErrorKind::UnknownField(key)));
93 }
94 };
95 unsafe { ps.mark_initialized(index) };
96 }
97 trace!("Finished deserializing \x1b[1;36mstruct\x1b[0m");
98 ps.build_in_place()
99 }
100 Poke::List(list_uninit) => {
101 trace!("Deserializing \x1b[1;36marray\x1b[0m");
102
103 parser.expect_array_start()?;
105
106 let mut pl = list_uninit.init(None).unwrap_or_else(|_| {
108 panic!("Failed to initialize list");
109 });
110
111 let mut index = 0;
112 while let Some(has_element) = parser.parse_array_element()? {
113 if !has_element {
114 break;
115 }
116
117 trace!("Processing array item at index: \x1b[1;33m{}\x1b[0m", index);
118
119 let data = OpaqueUninit::new(unsafe { std::alloc::alloc(shape.layout) });
120 let item_poke = unsafe { Poke::unchecked_new(data, shape) };
121
122 deserialize_value(parser, item_poke)?;
124
125 unsafe {
127 pl.push(data.assume_init());
128 }
129
130 index += 1;
131 }
132
133 trace!(
134 "Finished deserializing \x1b[1;36marray\x1b[0m with {} items",
135 index
136 );
137 pl.build_in_place()
138 }
139 Poke::Map(pm) => {
140 trace!("Deserializing \x1b[1;36mhashmap\x1b[0m");
141
142 let first_key = parser.expect_object_start()?;
144
145 let mut pm = pm
147 .init(None)
148 .unwrap_or_else(|_| panic!("Failed to initialize map")); let mut current_key = first_key;
152 while let Some(key) = current_key {
153 trace!("Processing hashmap key: \x1b[1;33m{}\x1b[0m", key);
154
155 let key_data = OpaqueUninit::new(unsafe { std::alloc::alloc(pm.def.k.layout) });
157 let key_poke = unsafe { Poke::unchecked_new(key_data, pm.def.k) };
158 let scalar_key_poke = key_poke.into_scalar();
159 scalar_key_poke.parse(&key).unwrap(); let value_data = OpaqueUninit::new(unsafe { std::alloc::alloc(pm.def.v.layout) });
163 let value_poke = unsafe { Poke::unchecked_new(value_data, pm.def.v) };
164
165 deserialize_value(parser, value_poke)?;
167
168 unsafe {
170 pm.insert(key_data.assume_init(), value_data.assume_init());
171 }
172
173 current_key = parser.parse_object_key()?;
175 }
176
177 trace!("Finished deserializing \x1b[1;36mhashmap\x1b[0m");
178 pm.build_in_place()
179 }
180 Poke::Enum(pe) => {
181 trace!("Deserializing \x1b[1;36menum\x1b[0m");
182 let variant_str = parser.parse_string()?;
184
185 let pe = pe.set_variant_by_name(&variant_str).map_err(|_| {
186 parser.make_error(JsonParseErrorKind::Custom(format!(
187 "Invalid enum variant: {}",
188 variant_str
189 )))
190 })?;
191
192 trace!("Finished deserializing \x1b[1;36menum\x1b[0m");
193 pe.build_in_place()
194 }
195 };
196 Ok(opaque)
197}