1use std::borrow::Cow;
2
3use ::serde::de::DeserializeSeed;
4use ::serde::de::EnumAccess;
5use ::serde::de::IntoDeserializer;
6use ::serde::de::MapAccess;
7use ::serde::de::SeqAccess;
8use ::serde::de::VariantAccess;
9use ::serde::de::Visitor;
10use ::serde::forward_to_deserialize_any;
11
12use super::ParseOptions;
13use super::common::Range;
14use super::errors::ParseError;
15use super::errors::ParseErrorKind;
16use super::tokens::Token;
17use crate::parser::JsoncParser;
18
19pub fn parse_to_serde_value<T: ::serde::de::DeserializeOwned>(
57 text: &str,
58 parse_options: &ParseOptions,
59) -> Result<Option<T>, ParseError> {
60 let mut parser = JsoncParser::new(text, parse_options);
61
62 let token = parser.scan()?;
63 match token {
64 None => Ok(None),
65 Some(token) => {
66 parser.put_back(token);
67 let value = T::deserialize(&mut parser)?;
68 if parser.scan()?.is_some() {
69 return Err(
70 parser
71 .scanner
72 .create_error_for_current_token(ParseErrorKind::MultipleRootJsonValues),
73 );
74 }
75 Ok(Some(value))
76 }
77 }
78}
79
80impl ::serde::de::Error for ParseError {
81 fn custom<T: std::fmt::Display>(msg: T) -> Self {
82 ParseError::custom_err(msg.to_string())
83 }
84}
85
86impl<'de> ::serde::Deserializer<'de> for &mut JsoncParser<'de> {
87 type Error = ParseError;
88
89 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
90 match self.scan()? {
91 None => Err(ParseError::custom_err("unexpected end of input".to_string())),
92 Some(token) => deserialize_token(self, token, visitor),
93 }
94 }
95
96 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
97 match self.scan()? {
98 Some(Token::Null) => visitor.visit_none(),
99 Some(token) => {
100 self.put_back(token);
101 visitor.visit_some(self)
102 }
103 None => visitor.visit_none(),
104 }
105 }
106
107 fn deserialize_enum<V: Visitor<'de>>(
108 self,
109 _name: &'static str,
110 _variants: &'static [&'static str],
111 visitor: V,
112 ) -> Result<V::Value, Self::Error> {
113 let token = self.scan()?;
114 let token_range = Range::new(self.scanner.token_start(), self.scanner.token_end());
115 let text = self.text;
116 let result = match token {
117 Some(Token::String(s)) => {
118 let variant: String = s.into_owned();
119 visitor.visit_enum(variant.into_deserializer())
120 }
121 Some(Token::OpenBrace) => {
122 let key = match self.scan()? {
124 Some(Token::String(s)) => s.into_owned(),
125 _ => {
126 return Err(ParseError::new(
127 token_range,
128 ParseErrorKind::Custom("expected a string key for enum variant".to_string()),
129 text,
130 ));
131 }
132 };
133
134 self.scan_object_colon()?;
136
137 let result = visitor.visit_enum(ObjectEnumAccess {
138 parser: self,
139 variant: key,
140 });
141 result.and_then(|v| {
142 match self.scan()? {
144 Some(Token::CloseBrace) => Ok(v),
145 _ => Err(
146 self
147 .scanner
148 .create_error_for_current_token(ParseErrorKind::UnterminatedObject),
149 ),
150 }
151 })
152 }
153 _ => {
154 return Err(ParseError::new(
155 token_range,
156 ParseErrorKind::Custom("expected a string or object for enum".to_string()),
157 text,
158 ));
159 }
160 };
161 result.map_err(|e| e.with_position(token_range, text))
162 }
163
164 fn deserialize_newtype_struct<V: Visitor<'de>>(
165 self,
166 _name: &'static str,
167 visitor: V,
168 ) -> Result<V::Value, Self::Error> {
169 visitor.visit_newtype_struct(self)
170 }
171
172 forward_to_deserialize_any! {
173 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
174 char str string bytes byte_buf unit unit_struct
175 seq tuple tuple_struct map struct identifier ignored_any
176 }
177}
178
179fn deserialize_token<'de, V: Visitor<'de>>(
180 parser: &mut JsoncParser<'de>,
181 token: Token<'de>,
182 visitor: V,
183) -> Result<V::Value, ParseError> {
184 let token_range = Range::new(parser.scanner.token_start(), parser.scanner.token_end());
185 let text = parser.text;
186 let result = match token {
187 Token::Null => visitor.visit_unit(),
188 Token::Boolean(b) => visitor.visit_bool(b),
189 Token::Number(n) => visit_number(n, visitor),
190 Token::String(s) => match s {
191 Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
192 Cow::Owned(o) => visitor.visit_string(o),
193 },
194 Token::OpenBracket => {
195 parser.enter_container()?;
196 let result = visitor.visit_seq(ScannerSeqAccess { parser, first: true });
197 parser.exit_container();
198 result
199 }
200 Token::OpenBrace => {
201 parser.enter_container()?;
202 let result = visitor.visit_map(ScannerMapAccess { parser, first: true });
203 parser.exit_container();
204 result
205 }
206 other => return Err(parser.unexpected_token_error(&other)),
207 };
208 result.map_err(|e| e.with_position(token_range, text))
209}
210
211fn visit_number<'de, V: Visitor<'de>>(raw: &str, visitor: V) -> Result<V::Value, ParseError> {
214 let trimmed = raw.trim_start_matches(['-', '+']);
216 if trimmed.len() > 2 && (trimmed.starts_with("0x") || trimmed.starts_with("0X")) {
217 let hex_part = &trimmed[2..];
218 match i64::from_str_radix(hex_part, 16) {
219 Ok(val) => {
220 let val = if raw.starts_with('-') { -val } else { val };
221 return visitor.visit_i64(val);
222 }
223 Err(_) => return visitor.visit_str(raw),
224 }
225 }
226
227 let num_str = raw.trim_start_matches('+');
229
230 if let Ok(v) = num_str.parse::<i64>() {
231 return visitor.visit_i64(v);
232 }
233 if let Ok(v) = num_str.parse::<u64>() {
234 return visitor.visit_u64(v);
235 }
236 if let Ok(v) = num_str.parse::<f64>() {
237 return visitor.visit_f64(v);
238 }
239
240 visitor.visit_str(raw)
242}
243
244struct ScannerSeqAccess<'a, 'b> {
247 parser: &'b mut JsoncParser<'a>,
248 first: bool,
249}
250
251impl<'de, 'b> SeqAccess<'de> for ScannerSeqAccess<'de, 'b> {
252 type Error = ParseError;
253
254 fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> {
255 let token = if self.first {
256 self.first = false;
257 self.parser.scan()?
258 } else {
259 self.parser.scan_array_comma()?
260 };
261
262 match token {
263 Some(Token::CloseBracket) => Ok(None),
264 Some(token) => {
265 self.parser.put_back(token);
266 seed.deserialize(&mut *self.parser).map(Some)
267 }
268 None => Err(
269 self
270 .parser
271 .scanner
272 .create_error_for_current_token(ParseErrorKind::UnterminatedArray),
273 ),
274 }
275 }
276}
277
278struct ScannerMapAccess<'a, 'b> {
281 parser: &'b mut JsoncParser<'a>,
282 first: bool,
283}
284
285impl<'de, 'b> MapAccess<'de> for ScannerMapAccess<'de, 'b> {
286 type Error = ParseError;
287
288 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> {
289 let key = self.parser.scan_object_entry(self.first)?;
290 self.first = false;
291
292 match key {
293 None => Ok(None),
294 Some(key) => {
295 let key_str = key.into_string();
296 seed
297 .deserialize(<String as IntoDeserializer<Self::Error>>::into_deserializer(key_str))
298 .map(Some)
299 }
300 }
301 }
302
303 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value, Self::Error> {
304 self.parser.scan_object_colon()?;
305 seed.deserialize(&mut *self.parser)
306 }
307}
308
309struct ObjectEnumAccess<'a, 'b> {
312 parser: &'b mut JsoncParser<'a>,
313 variant: String,
314}
315
316impl<'de, 'b> EnumAccess<'de> for ObjectEnumAccess<'de, 'b> {
317 type Error = ParseError;
318 type Variant = ObjectVariantAccess<'de, 'b>;
319
320 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> {
321 let variant = seed.deserialize(<String as IntoDeserializer<Self::Error>>::into_deserializer(
322 self.variant,
323 ))?;
324 Ok((variant, ObjectVariantAccess { parser: self.parser }))
325 }
326}
327
328struct ObjectVariantAccess<'a, 'b> {
329 parser: &'b mut JsoncParser<'a>,
330}
331
332impl<'de, 'b> VariantAccess<'de> for ObjectVariantAccess<'de, 'b> {
333 type Error = ParseError;
334
335 fn unit_variant(self) -> Result<(), Self::Error> {
336 ::serde::Deserialize::deserialize(&mut *self.parser)
337 }
338
339 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value, Self::Error> {
340 seed.deserialize(&mut *self.parser)
341 }
342
343 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> {
344 match self.parser.scan()? {
345 Some(Token::OpenBracket) => {
346 self.parser.enter_container()?;
347 let result = visitor.visit_seq(ScannerSeqAccess {
348 parser: self.parser,
349 first: true,
350 });
351 self.parser.exit_container();
352 result
353 }
354 _ => Err(ParseError::custom_err(
355 "expected an array for tuple variant".to_string(),
356 )),
357 }
358 }
359
360 fn struct_variant<V: Visitor<'de>>(
361 self,
362 _fields: &'static [&'static str],
363 visitor: V,
364 ) -> Result<V::Value, Self::Error> {
365 match self.parser.scan()? {
366 Some(Token::OpenBrace) => {
367 self.parser.enter_container()?;
368 let result = visitor.visit_map(ScannerMapAccess {
369 parser: self.parser,
370 first: true,
371 });
372 self.parser.exit_container();
373 result
374 }
375 _ => Err(ParseError::custom_err(
376 "expected an object for struct variant".to_string(),
377 )),
378 }
379 }
380}
381
382#[cfg(test)]
383mod tests {
384 use pretty_assertions::assert_eq;
385 use serde_json::Value as SerdeValue;
386 use std::str::FromStr;
387
388 use super::*;
389
390 #[test]
391 fn it_should_error_when_has_error() {
392 assert_has_error(
393 "[][]",
394 "Text cannot contain more than one JSON value on line 1 column 3",
395 );
396 }
397
398 fn assert_has_error(text: &str, message: &str) {
399 let result = parse_to_serde_value::<SerdeValue>(text, &Default::default());
400 match result {
401 Ok(_) => panic!("Expected error, but did not find one."),
402 Err(err) => assert_eq!(err.to_string(), message),
403 }
404 }
405
406 #[test]
407 fn it_should_parse_to_serde_value() {
408 let result = parse_to_serde_value::<SerdeValue>(
409 r#"{ "a": { "a1": 5 }, "b": [0.3e+025], "c": "c1", "d": true, "e": false, "f": null }"#,
410 &Default::default(),
411 )
412 .unwrap();
413
414 let mut expected_value = serde_json::map::Map::new();
415 expected_value.insert("a".to_string(), {
416 let mut inner_obj = serde_json::map::Map::new();
417 inner_obj.insert(
418 "a1".to_string(),
419 SerdeValue::Number(serde_json::Number::from_str("5").unwrap()),
420 );
421 SerdeValue::Object(inner_obj)
422 });
423 expected_value.insert("b".to_string(), {
424 let mut inner_array = Vec::new();
425 inner_array.push(SerdeValue::Number(serde_json::Number::from_str("0.3e+025").unwrap()));
426 SerdeValue::Array(inner_array)
427 });
428 expected_value.insert("c".to_string(), SerdeValue::String("c1".to_string()));
429 expected_value.insert("d".to_string(), SerdeValue::Bool(true));
430 expected_value.insert("e".to_string(), SerdeValue::Bool(false));
431 expected_value.insert("f".to_string(), SerdeValue::Null);
432
433 assert_eq!(result, Some(SerdeValue::Object(expected_value)));
434 }
435
436 #[test]
437 fn it_should_parse_hexadecimal_numbers_to_decimal() {
438 let result = parse_to_serde_value::<SerdeValue>(
439 r#"{
440 "hex1": 0x7DF,
441 "hex2": 0xFF,
442 "hex3": 0x10
443 }"#,
444 &Default::default(),
445 )
446 .unwrap();
447
448 let mut expected_value = serde_json::map::Map::new();
449 expected_value.insert("hex1".to_string(), SerdeValue::Number(serde_json::Number::from(2015)));
450 expected_value.insert("hex2".to_string(), SerdeValue::Number(serde_json::Number::from(255)));
451 expected_value.insert("hex3".to_string(), SerdeValue::Number(serde_json::Number::from(16)));
452
453 assert_eq!(result, Some(SerdeValue::Object(expected_value)));
454 }
455
456 #[test]
457 fn it_should_parse_unary_plus_numbers() {
458 let result = parse_to_serde_value::<SerdeValue>(
459 r#"{
460 "pos1": +42,
461 "pos2": +0.5,
462 "pos3": +1e10
463 }"#,
464 &Default::default(),
465 )
466 .unwrap();
467
468 let mut expected_value = serde_json::map::Map::new();
469 expected_value.insert("pos1".to_string(), SerdeValue::Number(serde_json::Number::from(42)));
470 expected_value.insert(
471 "pos2".to_string(),
472 SerdeValue::Number(serde_json::Number::from_str("0.5").unwrap()),
473 );
474 expected_value.insert(
475 "pos3".to_string(),
476 SerdeValue::Number(serde_json::Number::from_str("1e10").unwrap()),
477 );
478
479 assert_eq!(result, Some(SerdeValue::Object(expected_value)));
480 }
481
482 #[test]
483 fn it_should_deserialize_to_struct() {
484 #[derive(::serde::Deserialize, Debug, PartialEq)]
485 #[serde(crate = "::serde")]
486 struct Config {
487 name: String,
488 value: u32,
489 enabled: bool,
490 }
491
492 let result: Option<Config> = parse_to_serde_value(
493 r#"{ "name": "test", "value": 42, "enabled": true }"#,
494 &Default::default(),
495 )
496 .unwrap();
497
498 assert_eq!(
499 result,
500 Some(Config {
501 name: "test".to_string(),
502 value: 42,
503 enabled: true,
504 })
505 );
506 }
507
508 #[test]
509 fn it_should_report_position_on_type_error() {
510 #[derive(::serde::Deserialize, Debug)]
511 #[serde(crate = "::serde")]
512 #[allow(dead_code)]
513 struct Config {
514 name: String,
515 }
516
517 let text = r#"{
518 "name": true
519}"#;
520 let err = parse_to_serde_value::<Config>(text, &Default::default()).unwrap_err();
521 assert_eq!(err.line_display(), 2);
523 assert_eq!(err.column_display(), 11);
524 assert!(err.to_string().contains("invalid type"), "got: {}", err);
525 }
526
527 #[test]
528 fn it_should_deserialize_option_fields() {
529 #[derive(::serde::Deserialize, Debug, PartialEq)]
530 #[serde(crate = "::serde")]
531 struct Config {
532 a: Option<u32>,
533 b: Option<u32>,
534 }
535
536 let result: Option<Config> = parse_to_serde_value(r#"{ "a": 5, "b": null }"#, &Default::default()).unwrap();
537
538 assert_eq!(result, Some(Config { a: Some(5), b: None }));
539 }
540
541 #[test]
542 fn it_should_deserialize_enum() {
543 #[derive(::serde::Deserialize, Debug, PartialEq)]
544 #[serde(crate = "::serde")]
545 enum Color {
546 Red,
547 Green,
548 Blue,
549 }
550
551 #[derive(::serde::Deserialize, Debug, PartialEq)]
552 #[serde(crate = "::serde")]
553 struct Config {
554 color: Color,
555 }
556
557 let result: Option<Config> = parse_to_serde_value(r#"{ "color": "Red" }"#, &Default::default()).unwrap();
558
559 assert_eq!(result, Some(Config { color: Color::Red }));
560 }
561
562 #[test]
563 fn it_should_deserialize_complex_enum() {
564 #[derive(::serde::Deserialize, Debug, PartialEq)]
565 #[serde(crate = "::serde")]
566 enum Shape {
567 Circle(f64),
568 Rectangle { width: f64, height: f64 },
569 }
570
571 let result: Option<Shape> = parse_to_serde_value(r#"{ "Circle": 5.0 }"#, &Default::default()).unwrap();
572 assert_eq!(result, Some(Shape::Circle(5.0)));
573
574 let result: Option<Shape> = parse_to_serde_value(
575 r#"{ "Rectangle": { "width": 3.0, "height": 4.0 } }"#,
576 &Default::default(),
577 )
578 .unwrap();
579 assert_eq!(
580 result,
581 Some(Shape::Rectangle {
582 width: 3.0,
583 height: 4.0
584 })
585 );
586 }
587
588 #[test]
589 fn it_should_return_none_for_empty_input() {
590 let result = parse_to_serde_value::<SerdeValue>("", &Default::default()).unwrap();
591 assert_eq!(result, None);
592 }
593
594 #[test]
595 fn it_should_handle_comments_in_jsonc() {
596 #[derive(::serde::Deserialize, Debug, PartialEq)]
597 #[serde(crate = "::serde")]
598 struct Config {
599 value: u32,
600 }
601
602 let result: Option<Config> = parse_to_serde_value(
603 r#"{
604 // this is a comment
605 "value": 42 /* inline comment */
606 }"#,
607 &Default::default(),
608 )
609 .unwrap();
610
611 assert_eq!(result, Some(Config { value: 42 }));
612 }
613}