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::True => Ok(Spanned {
90 node: Outcome::Scalar(Scalar::Bool(true)),
91 span,
92 }),
93 Token::False => Ok(Spanned {
94 node: Outcome::Scalar(Scalar::Bool(false)),
95 span,
96 }),
97 Token::Null => Ok(Spanned {
98 node: Outcome::Scalar(Scalar::Null),
99 span,
100 }),
101 Token::LBrace => Ok(Spanned {
102 node: Outcome::ObjectStarted,
103 span,
104 }),
105 Token::RBrace => {
106 if expectation == Expectation::ObjectKeyOrObjectClose {
107 Ok(Spanned {
108 node: Outcome::ObjectEnded,
109 span,
110 })
111 } else {
112 trace!("Did not expect closing brace, expected {:?}", expectation);
113 Err(DeserErrorKind::UnexpectedChar {
114 got: '}',
115 wanted: "a value",
116 }
117 .with_span(span))
118 }
119 }
120 Token::LBracket => Ok(Spanned {
121 node: Outcome::ListStarted,
122 span,
123 }),
124 Token::RBracket => {
125 if expectation == Expectation::ListItemOrListClose {
126 Ok(Spanned {
127 node: Outcome::ListEnded,
128 span,
129 })
130 } else {
131 Err(DeserErrorKind::UnexpectedChar {
132 got: ']',
133 wanted: "a value",
134 }
135 .with_span(span))
136 }
137 }
138 Token::Colon => {
139 if expectation == Expectation::ObjectVal {
140 expectation = Expectation::Value;
141 continue;
142 } else {
143 trace!("Did not expect ObjectValue, expected {:?}", expectation);
144 Err(DeserErrorKind::UnexpectedChar {
145 got: ':',
146 wanted: "a value, not a colon",
147 }
148 .with_span(span))
149 }
150 }
151 Token::Comma => match expectation {
152 Expectation::ListItemOrListClose | Expectation::ObjectKeyOrObjectClose => {
153 expectation = Expectation::Value;
154 continue;
155 }
156 other => {
157 trace!("Did not expect comma, expected {:?}", other);
158 Err(DeserErrorKind::UnexpectedChar {
159 got: ',',
160 wanted: "<value or key>",
161 }
162 .with_span(span))
163 }
164 },
165 Token::Eof => {
166 return (
167 nd,
168 Err(DeserErrorKind::UnexpectedEof {
169 wanted: "any value (got EOF)",
170 }
171 .with_span(span)),
172 );
173 }
174 };
175
176 return (nd, res);
177 }
178 }
179
180 fn skip<'input, 'facet, 'shape>(
181 &mut self,
182 nd: NextData<'input, 'facet, 'shape>,
183 ) -> NextResult<
184 'input,
185 'facet,
186 'shape,
187 Span,
188 Spanned<DeserErrorKind<'shape>>,
189 Self::SpanType,
190 Self::Input<'input>,
191 >
192 where
193 'shape: 'input,
194 {
195 trace!("Starting skip at offset {}", nd.start());
196 let input = &nd.input()[nd.start()..];
197 let mut tokenizer = Tokenizer::new(input);
198
199 loop {
200 let token = match tokenizer.next_token() {
201 Ok(token) => token,
202 Err(err) => {
203 trace!("Tokenizer error on initial token: {:?}", err.kind);
204 return (nd, Err(convert_token_error(err)));
205 }
206 };
207
208 let res = match token.node {
209 Token::LBrace | Token::LBracket => {
210 let mut depth = 1;
211 let mut last_span = token.span;
212 while depth > 0 {
213 let token = match tokenizer.next_token() {
214 Ok(token) => token,
215 Err(err) => {
216 trace!("Tokenizer error while skipping container: {:?}", err.kind);
217 return (nd, Err(convert_token_error(err)));
218 }
219 };
220
221 match token.node {
222 Token::LBrace | Token::LBracket => {
223 depth += 1;
224 last_span = token.span;
225 }
226 Token::RBrace | Token::RBracket => {
227 depth -= 1;
228 last_span = token.span;
229 }
230 _ => {
231 last_span = token.span;
232 }
233 }
234 }
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 => (nd, Ok(token.span)),
244 Token::Colon => {
245 continue;
247 }
248 other => (
249 nd,
250 Err(DeserErrorKind::UnexpectedChar {
251 got: format!("{:?}", other).chars().next().unwrap_or('?'),
252 wanted: "value",
253 }
254 .with_span(Span::new(token.span.start(), token.span.len()))),
255 ),
256 };
257 let (nd, mut span) = res;
258 if let Ok(valid_span) = &mut span {
259 let offset = nd.start();
260 valid_span.start += offset;
261 }
262 return (nd, span);
263 }
264 }
265}
266
267fn convert_token_error(err: TokenError) -> Spanned<DeserErrorKind<'static>> {
268 match err.kind {
269 TokenErrorKind::UnexpectedCharacter(c) => DeserErrorKind::UnexpectedChar {
270 got: c,
271 wanted: "valid JSON character",
272 }
273 .with_span(err.span),
274 TokenErrorKind::UnexpectedEof(why) => {
275 DeserErrorKind::UnexpectedEof { wanted: why }.with_span(err.span)
276 }
277 TokenErrorKind::InvalidUtf8(s) => DeserErrorKind::InvalidUtf8(s).with_span(err.span),
278 TokenErrorKind::NumberOutOfRange(number) => {
279 DeserErrorKind::NumberOutOfRange(number).with_span(err.span)
280 }
281 }
282}