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