1use alloc::format;
2
3use facet_core::Facet;
4use facet_deserialize::{
5 Cooked, Expectation, Format, NextData, NextResult, Outcome, Scalar, Span, Spannable, Spanned,
6};
7pub use facet_deserialize::{DeserError, DeserErrorKind};
8use log::trace;
9
10use crate::tokenizer::{Token, TokenError, TokenErrorKind, Tokenizer};
11
12pub fn from_slice<'input, 'facet, 'shape, T: Facet<'facet>>(
14 input: &'input [u8],
15) -> Result<T, DeserError<'input, 'shape>>
16where
17 'input: 'facet,
18{
19 facet_deserialize::deserialize(input, crate::Json)
20}
21
22pub fn from_str<'input, 'facet, 'shape, T: Facet<'facet>>(
24 input: &'input str,
25) -> Result<T, DeserError<'input, 'shape>>
26where
27 'input: 'facet,
28{
29 from_slice(input.as_bytes())
30}
31
32impl Format for crate::Json {
33 type Input<'input> = [u8];
34 type SpanType = Cooked;
35
36 fn source(&self) -> &'static str {
37 "json"
38 }
39
40 fn next<'input, 'facet, 'shape>(
41 &mut self,
42 nd: NextData<'input, 'facet, 'shape>,
43 mut expectation: Expectation,
44 ) -> NextResult<
45 'input,
46 'facet,
47 'shape,
48 Spanned<Outcome<'input>, Self::SpanType>,
49 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
50 Self::SpanType,
51 Self::Input<'input>,
52 >
53 where
54 'shape: 'input,
55 {
56 let input = &nd.input()[nd.start()..];
57 let mut tokenizer = Tokenizer::new(input);
58
59 loop {
60 let token = match tokenizer.next_token() {
61 Ok(token) => token,
62 Err(err) => {
63 trace!("Tokenizer error in next: {:?}", err.kind);
64 return (nd, Err(convert_token_error(err)));
65 }
66 };
67
68 let token_offset = nd.start();
70 let span = Span::new(token.span.start() + token_offset, token.span.len());
71
72 let res = match token.node {
73 Token::String(s) => Ok(Spanned {
74 node: Outcome::Scalar(Scalar::String(s)),
75 span,
76 }),
77 Token::F64(n) => Ok(Spanned {
78 node: Outcome::Scalar(Scalar::F64(n)),
79 span,
80 }),
81 Token::I64(n) => Ok(Spanned {
82 node: Outcome::Scalar(Scalar::I64(n)),
83 span,
84 }),
85 Token::U64(n) => Ok(Spanned {
86 node: Outcome::Scalar(Scalar::U64(n)),
87 span,
88 }),
89 Token::U128(n) => Ok(Spanned {
90 node: Outcome::Scalar(Scalar::U128(n)),
91 span,
92 }),
93 Token::I128(n) => Ok(Spanned {
94 node: Outcome::Scalar(Scalar::I128(n)),
95 span,
96 }),
97 Token::True => Ok(Spanned {
98 node: Outcome::Scalar(Scalar::Bool(true)),
99 span,
100 }),
101 Token::False => Ok(Spanned {
102 node: Outcome::Scalar(Scalar::Bool(false)),
103 span,
104 }),
105 Token::Null => Ok(Spanned {
106 node: Outcome::Scalar(Scalar::Null),
107 span,
108 }),
109 Token::LBrace => Ok(Spanned {
110 node: Outcome::ObjectStarted,
111 span,
112 }),
113 Token::RBrace => {
114 if expectation == Expectation::ObjectKeyOrObjectClose {
115 Ok(Spanned {
116 node: Outcome::ObjectEnded,
117 span,
118 })
119 } else {
120 trace!("Did not expect closing brace, expected {expectation:?}");
121 Err(DeserErrorKind::UnexpectedChar {
122 got: '}',
123 wanted: "a value",
124 }
125 .with_span(span))
126 }
127 }
128 Token::LBracket => Ok(Spanned {
129 node: Outcome::ListStarted,
130 span,
131 }),
132 Token::RBracket => {
133 if expectation == Expectation::ListItemOrListClose {
134 Ok(Spanned {
135 node: Outcome::ListEnded,
136 span,
137 })
138 } else {
139 Err(DeserErrorKind::UnexpectedChar {
140 got: ']',
141 wanted: "a value",
142 }
143 .with_span(span))
144 }
145 }
146 Token::Colon => {
147 if expectation == Expectation::ObjectVal {
148 expectation = Expectation::Value;
149 continue;
150 } else {
151 trace!("Did not expect ObjectValue, expected {expectation:?}");
152 Err(DeserErrorKind::UnexpectedChar {
153 got: ':',
154 wanted: "a value, not a colon",
155 }
156 .with_span(span))
157 }
158 }
159 Token::Comma => match expectation {
160 Expectation::ListItemOrListClose | Expectation::ObjectKeyOrObjectClose => {
161 expectation = Expectation::Value;
162 continue;
163 }
164 other => {
165 trace!("Did not expect comma, expected {other:?}");
166 Err(DeserErrorKind::UnexpectedChar {
167 got: ',',
168 wanted: "<value or key>",
169 }
170 .with_span(span))
171 }
172 },
173 Token::Eof => {
174 return (
175 nd,
176 Err(DeserErrorKind::UnexpectedEof {
177 wanted: "any value (got EOF)",
178 }
179 .with_span(span)),
180 );
181 }
182 };
183
184 return (nd, res);
185 }
186 }
187
188 fn skip<'input, 'facet, 'shape>(
189 &mut self,
190 nd: NextData<'input, 'facet, 'shape>,
191 ) -> NextResult<
192 'input,
193 'facet,
194 'shape,
195 Span,
196 Spanned<DeserErrorKind<'shape>>,
197 Self::SpanType,
198 Self::Input<'input>,
199 >
200 where
201 'shape: 'input,
202 {
203 trace!("Starting skip at offset {}", nd.start());
204 let input = &nd.input()[nd.start()..];
205 let mut tokenizer = Tokenizer::new(input);
206
207 loop {
208 let token = match tokenizer.next_token() {
209 Ok(token) => token,
210 Err(err) => {
211 trace!("Tokenizer error on initial token: {:?}", err.kind);
212 return (nd, Err(convert_token_error(err)));
213 }
214 };
215
216 let res = match token.node {
217 Token::LBrace | Token::LBracket => {
218 let mut depth = 1;
219 let mut last_span = token.span;
220 while depth > 0 {
221 let token = match tokenizer.next_token() {
222 Ok(token) => token,
223 Err(err) => {
224 trace!("Tokenizer error while skipping container: {:?}", err.kind);
225 return (nd, Err(convert_token_error(err)));
226 }
227 };
228
229 match token.node {
230 Token::LBrace | Token::LBracket => {
231 depth += 1;
232 last_span = token.span;
233 }
234 Token::RBrace | Token::RBracket => {
235 depth -= 1;
236 last_span = token.span;
237 }
238 _ => {
239 last_span = token.span;
240 }
241 }
242 }
243 (nd, Ok(last_span))
244 }
245 Token::String(_)
246 | Token::F64(_)
247 | Token::I64(_)
248 | Token::U64(_)
249 | Token::True
250 | Token::False
251 | Token::Null => (nd, Ok(token.span)),
252 Token::Colon => {
253 continue;
255 }
256 other => (
257 nd,
258 Err(DeserErrorKind::UnexpectedChar {
259 got: format!("{other:?}").chars().next().unwrap_or('?'),
260 wanted: "value",
261 }
262 .with_span(Span::new(token.span.start(), token.span.len()))),
263 ),
264 };
265 let (nd, mut span) = res;
266 if let Ok(valid_span) = &mut span {
267 let offset = nd.start();
268 valid_span.start += offset;
269 }
270 return (nd, span);
271 }
272 }
273}
274
275fn convert_token_error(err: TokenError) -> Spanned<DeserErrorKind<'static>> {
276 match err.kind {
277 TokenErrorKind::UnexpectedCharacter(c) => DeserErrorKind::UnexpectedChar {
278 got: c,
279 wanted: "valid JSON character",
280 }
281 .with_span(err.span),
282 TokenErrorKind::UnexpectedEof(why) => {
283 DeserErrorKind::UnexpectedEof { wanted: why }.with_span(err.span)
284 }
285 TokenErrorKind::InvalidUtf8(s) => DeserErrorKind::InvalidUtf8(s).with_span(err.span),
286 TokenErrorKind::NumberOutOfRange(number) => {
287 DeserErrorKind::NumberOutOfRange(number).with_span(err.span)
288 }
289 }
290}