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