Skip to content

Commit 172bdd6

Browse files
authored
Merge pull request #394 from MomoLangenstein/393-better-serde-errors
2 parents f7e8417 + 021eb4c commit 172bdd6

8 files changed

+583
-41
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- Fix issue [#301](https://github.com/ron-rs/ron/issues/301) with better error messages ([#354](https://github.com/ron-rs/ron/pull/354))
1111
- Fix issue [#337](https://github.com/ron-rs/ron/issues/337) by removing `decimal_floats` PrettyConfig option and unconditional decimals in floats ([#363](https://github.com/ron-rs/ron/pull/363))
1212
- Fix issue [#203](https://github.com/ron-rs/ron/issues/203) with full de error positioning ([#356](https://github.com/ron-rs/ron/pull/356))
13+
- Expand the `ron::Error` enum to distinguish `serde` errors like `NoSuchEnumVariant` and `MissingStructField` with error positioning ([#394](https://github.com/ron-rs/ron/pull/394))
1314
- Bump MSRV to 1.56.0 ([#396](https://github.com/ron-rs/ron/pull/396))
1415

1516
## [0.7.1] - 2022-06-15

src/de/mod.rs

+67-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod value;
2525
pub struct Deserializer<'de> {
2626
bytes: Bytes<'de>,
2727
newtype_variant: bool,
28+
last_identifier: Option<&'de str>,
2829
}
2930

3031
impl<'de> Deserializer<'de> {
@@ -46,6 +47,7 @@ impl<'de> Deserializer<'de> {
4647
let mut deserializer = Deserializer {
4748
bytes: Bytes::new(input)?,
4849
newtype_variant: false,
50+
last_identifier: None,
4951
};
5052

5153
deserializer.bytes.exts |= options.default_extensions;
@@ -528,7 +530,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
528530
let old_newtype_variant = self.newtype_variant;
529531
self.newtype_variant = false;
530532

531-
let value = visitor.visit_map(CommaSeparated::new(b')', self))?;
533+
let value = visitor
534+
.visit_map(CommaSeparated::new(b')', self))
535+
.map_err(|err| {
536+
struct_error_name(
537+
err,
538+
if !old_newtype_variant && !name.is_empty() {
539+
Some(name)
540+
} else {
541+
None
542+
},
543+
)
544+
})?;
545+
532546
self.bytes.comma()?;
533547

534548
if old_newtype_variant || self.bytes.consume(")") {
@@ -545,7 +559,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
545559

546560
fn deserialize_enum<V>(
547561
self,
548-
_name: &'static str,
562+
name: &'static str,
549563
_variants: &'static [&'static str],
550564
visitor: V,
551565
) -> Result<V::Value>
@@ -554,14 +568,30 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
554568
{
555569
self.newtype_variant = false;
556570

557-
visitor.visit_enum(Enum::new(self))
571+
match visitor.visit_enum(Enum::new(self)) {
572+
Ok(value) => Ok(value),
573+
Err(Error::NoSuchEnumVariant {
574+
expected,
575+
found,
576+
outer: None,
577+
}) if !name.is_empty() => Err(Error::NoSuchEnumVariant {
578+
expected,
579+
found,
580+
outer: Some(String::from(name)),
581+
}),
582+
Err(e) => Err(e),
583+
}
558584
}
559585

560586
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
561587
where
562588
V: Visitor<'de>,
563589
{
564-
visitor.visit_str(str::from_utf8(self.bytes.identifier()?).map_err(Error::from)?)
590+
let identifier = str::from_utf8(self.bytes.identifier()?).map_err(Error::from)?;
591+
592+
self.last_identifier = Some(identifier);
593+
594+
visitor.visit_str(identifier)
565595
}
566596

567597
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
@@ -699,6 +729,8 @@ impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
699729
where
700730
T: DeserializeSeed<'de>,
701731
{
732+
let newtype_variant = self.de.last_identifier;
733+
702734
self.de.bytes.skip_ws()?;
703735

704736
if self.de.bytes.consume("(") {
@@ -710,7 +742,9 @@ impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
710742
.exts
711743
.contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
712744

713-
let val = seed.deserialize(&mut *self.de)?;
745+
let val = seed
746+
.deserialize(&mut *self.de)
747+
.map_err(|err| struct_error_name(err, newtype_variant))?;
714748

715749
self.de.newtype_variant = false;
716750

@@ -739,8 +773,35 @@ impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
739773
where
740774
V: Visitor<'de>,
741775
{
776+
let struct_variant = self.de.last_identifier;
777+
742778
self.de.bytes.skip_ws()?;
743779

744-
self.de.deserialize_struct("", fields, visitor)
780+
self.de
781+
.deserialize_struct("", fields, visitor)
782+
.map_err(|err| struct_error_name(err, struct_variant))
783+
}
784+
}
785+
786+
fn struct_error_name(error: Error, name: Option<&str>) -> Error {
787+
match error {
788+
Error::NoSuchStructField {
789+
expected,
790+
found,
791+
outer: None,
792+
} => Error::NoSuchStructField {
793+
expected,
794+
found,
795+
outer: name.map(ToOwned::to_owned),
796+
},
797+
Error::MissingStructField { field, outer: None } => Error::MissingStructField {
798+
field,
799+
outer: name.map(ToOwned::to_owned),
800+
},
801+
Error::DuplicateStructField { field, outer: None } => Error::DuplicateStructField {
802+
field,
803+
outer: name.map(ToOwned::to_owned),
804+
},
805+
e => e,
745806
}
746807
}

0 commit comments

Comments
 (0)