shapely_json/
from_json.rs1use crate::parser::{JsonParseErrorKind, JsonParseErrorWithContext, JsonParser};
2use shapely::{Partial, Shapely as _, error, trace, warn};
3
4pub fn from_json<'input>(
6 partial: &mut Partial,
7 json: &'input str,
8) -> Result<(), JsonParseErrorWithContext<'input>> {
9 use shapely::{Innards, Scalar};
10
11 trace!("Starting JSON deserialization");
12 let mut parser = JsonParser::new(json);
13
14 fn deserialize_value<'input>(
15 parser: &mut JsonParser<'input>,
16 partial: &mut Partial,
17 ) -> Result<(), JsonParseErrorWithContext<'input>> {
18 let shape_desc = partial.shape();
19 let shape = shape_desc.get();
20 trace!("Deserializing value with shape:\n{:?}", shape);
21
22 match &shape.innards {
23 Innards::Scalar(scalar) => {
24 let slot = partial.scalar_slot().expect("Scalar slot");
25 trace!("Deserializing \x1b[1;36mscalar\x1b[0m, \x1b[1;35m{scalar:?}\x1b[0m");
26
27 match scalar {
28 Scalar::String => slot.fill(parser.parse_string()?),
29 Scalar::U8 => slot.fill(parser.parse_u8()?),
30 Scalar::U16 => slot.fill(parser.parse_u16()?),
31 Scalar::U32 => slot.fill(parser.parse_u32()?),
32 Scalar::U64 => slot.fill(parser.parse_u64()?),
33 Scalar::I8 => slot.fill(parser.parse_i8()?),
34 Scalar::I16 => slot.fill(parser.parse_i16()?),
35 Scalar::I32 => slot.fill(parser.parse_i32()?),
36 Scalar::I64 => slot.fill(parser.parse_i64()?),
37 Scalar::F32 => slot.fill(parser.parse_f32()?),
38 Scalar::F64 => slot.fill(parser.parse_f64()?),
39 Scalar::Boolean => slot.fill(parser.parse_bool()?),
40 _ => {
41 warn!("Unsupported scalar type: {:?}", scalar);
42 return Err(parser.make_error(JsonParseErrorKind::Custom(format!(
43 "Unsupported scalar type: {:?}",
44 scalar
45 ))));
46 }
47 }
48 }
49 Innards::Struct { .. } => {
50 trace!("Deserializing \x1b[1;36mstruct\x1b[0m");
51
52 let mut first = true;
53 while let Some(key) = if first {
54 first = false;
55 parser.expect_object_start()?
56 } else {
57 parser.parse_object_key()?
58 } {
59 trace!("Processing struct key: \x1b[1;33m{}\x1b[0m", key);
60 let slot = partial
61 .slot_by_name(&key)
62 .map_err(|_| parser.make_error(JsonParseErrorKind::UnknownField(key)))?;
63 let mut partial_field = Partial::alloc(slot.shape());
64 deserialize_value(parser, &mut partial_field)?;
65 slot.fill_from_partial(partial_field);
66 }
67 trace!("Finished deserializing \x1b[1;36mstruct\x1b[0m");
68
69 }
72 Innards::Tuple { .. } => {
73 trace!("Deserializing \x1b[1;36mtuple\x1b[0m");
74
75 parser.expect_array_start()?;
77
78 let mut index = 0;
79 while let Some(has_element) = parser.parse_array_element()? {
80 if !has_element {
81 break;
82 }
83
84 let field_name = index.to_string();
85 trace!("Processing tuple index: \x1b[1;33m{}\x1b[0m", field_name);
86
87 let slot = partial.slot_by_name(&field_name).map_err(|_| {
88 parser.make_error(JsonParseErrorKind::Custom(format!(
89 "Tuple index out of bounds: {}",
90 index
91 )))
92 })?;
93
94 let mut partial_field = Partial::alloc(slot.shape());
95 deserialize_value(parser, &mut partial_field)?;
96 slot.fill_from_partial(partial_field);
97
98 index += 1;
99 }
100
101 trace!("Finished deserializing \x1b[1;36mtuple\x1b[0m");
102 }
103 Innards::TupleStruct { .. } => {
104 trace!("Deserializing \x1b[1;36mtuple struct\x1b[0m");
105
106 parser.expect_array_start()?;
108
109 let mut index = 0;
110 while let Some(has_element) = parser.parse_array_element()? {
111 if !has_element {
112 break;
113 }
114
115 let field_name = index.to_string();
116 trace!(
117 "Processing tuple struct index: \x1b[1;33m{}\x1b[0m",
118 field_name
119 );
120
121 let slot = partial.slot_by_name(&field_name).map_err(|_| {
122 parser.make_error(JsonParseErrorKind::Custom(format!(
123 "Tuple struct index out of bounds: {}",
124 index
125 )))
126 })?;
127
128 let mut partial_field = Partial::alloc(slot.shape());
129 deserialize_value(parser, &mut partial_field)?;
130 slot.fill_from_partial(partial_field);
131
132 index += 1;
133 }
134
135 trace!("Finished deserializing \x1b[1;36mtuple struct\x1b[0m");
136 }
137 Innards::List { item_shape, .. } => {
138 trace!("Deserializing \x1b[1;36marray\x1b[0m");
139
140 parser.expect_array_start()?;
142
143 let mut array_slot = partial.array_slot(None).expect("Array slot");
145
146 let mut index = 0;
147 while let Some(has_element) = parser.parse_array_element()? {
148 if !has_element {
149 break;
150 }
151
152 trace!("Processing array item at index: \x1b[1;33m{}\x1b[0m", index);
153
154 let mut item_partial = Partial::alloc(*item_shape);
156
157 deserialize_value(parser, &mut item_partial)?;
159
160 array_slot.push(item_partial);
162
163 index += 1;
164 }
165
166 trace!(
167 "Finished deserializing \x1b[1;36marray\x1b[0m with {} items",
168 index
169 );
170 }
171 Innards::Map { value_shape, .. } => {
172 trace!("Deserializing \x1b[1;36mhashmap\x1b[0m");
173
174 let first_key = parser.expect_object_start()?;
176
177 let mut hashmap_slot = partial.hashmap_slot(None).expect("HashMap slot");
179
180 let mut current_key = first_key;
182 while let Some(key) = current_key {
183 trace!("Processing hashmap key: \x1b[1;33m{}\x1b[0m", key);
184
185 let mut key_partial = Partial::alloc(String::shape_desc());
187 key_partial.scalar_slot().expect("String slot").fill(key);
188
189 let mut value_partial = Partial::alloc(*value_shape);
191
192 deserialize_value(parser, &mut value_partial)?;
194
195 hashmap_slot.insert(key_partial, value_partial);
197
198 current_key = parser.parse_object_key()?;
200 }
201
202 trace!("Finished deserializing \x1b[1;36mhashmap\x1b[0m");
203 }
204 _ => {
206 error!(
207 "Don't know how to parse this shape as JSON: {:?}",
208 shape.innards
209 );
210 return Err(parser.make_error(JsonParseErrorKind::Custom(format!(
211 "Don't know how to parse this shape as JSON: {:?}",
212 shape.innards
213 ))));
214 }
215 }
216 Ok(())
217 }
218
219 deserialize_value(&mut parser, partial)
220}