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