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