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