diff --git a/CHANGELOG.md b/CHANGELOG.md index c4285cacc..f51086598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix issue [#401](https://github.com/ron-rs/ron/issues/401) with correct raw struct name identifier parsing ([#402](https://github.com/ron-rs/ron/pull/402)) - Add `ron::value::RawValue` helper type which can (de)serialize any valid RON ([#407](https://github.com/ron-rs/ron/pull/407)) - Fix issue [#410](https://github.com/ron-rs/ron/issues/410) trailing comma parsing in tuples and `Some` ([#412](https://github.com/ron-rs/ron/pull/412)) +- Error instead of panic when deserializing non-identifiers as field names ([#415](https://github.com/ron-rs/ron/pull/415)) ## [0.8.0] - 2022-08-17 diff --git a/src/de/id.rs b/src/de/id.rs index 537ce5690..e7230da5f 100644 --- a/src/de/id.rs +++ b/src/de/id.rs @@ -40,35 +40,35 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_i8(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_i16(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_i32(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_i64(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } #[cfg(feature = "integer128")] @@ -76,35 +76,35 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_u8(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_u16(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_u32(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_u64(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } #[cfg(feature = "integer128")] @@ -112,105 +112,105 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_f32(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_f64(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_char(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_string(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_bytes(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_byte_buf(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_option(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_unit(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_unit_struct(self, _: &'static str, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_newtype_struct(self, _: &'static str, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_seq(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_tuple(self, _: usize, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_tuple_struct(self, _: &'static str, _: usize, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_map(self, _: V) -> Result where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_struct( @@ -222,7 +222,7 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_enum( @@ -234,7 +234,7 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { where V: Visitor<'b>, { - unimplemented!("IdDeserializer may only be used for identifiers") + Err(Error::ExpectedIdentifier) } fn deserialize_ignored_any(self, visitor: V) -> Result diff --git a/src/value/raw.rs b/src/value/raw.rs index 77c2cf648..493d0a50f 100644 --- a/src/value/raw.rs +++ b/src/value/raw.rs @@ -79,7 +79,7 @@ impl RawValue { /// Helper function to validate a RON string and turn it into a `RawValue`. pub fn from_boxed_ron(ron: Box) -> SpannedResult> { - match Options::default().from_str::<&Self>(&*ron) { + match Options::default().from_str::<&Self>(&ron) { Ok(_) => Ok(Self::from_boxed_str(ron)), Err(err) => Err(err), } diff --git a/tests/203_error_positions.rs b/tests/203_error_positions.rs index 0ef486a17..153e3f5ba 100644 --- a/tests/203_error_positions.rs +++ b/tests/203_error_positions.rs @@ -13,7 +13,7 @@ enum Test { StructVariant { a: bool, b: NonZeroU32, c: i32 }, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq)] // GRCOV_EXCL_LINE struct TypeError; impl<'de> Deserialize<'de> for TypeError { diff --git a/tests/non_identifier_identifier.rs b/tests/non_identifier_identifier.rs new file mode 100644 index 000000000..81b6c2cdc --- /dev/null +++ b/tests/non_identifier_identifier.rs @@ -0,0 +1,94 @@ +macro_rules! test_non_identifier { + ($test_name:ident => $deserialize_method:ident($($deserialize_param:expr),*)) => { + #[test] + fn $test_name() { + use serde::{Deserialize, Deserializer, de::Visitor, de::MapAccess}; + + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = FieldName; + + // GRCOV_EXCL_START + fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fmt.write_str("an error") + } + // GRCOV_EXCL_STOP + } + + struct FieldName; + + impl<'de> Deserialize<'de> for FieldName { + fn deserialize>(deserializer: D) + -> Result + { + deserializer.$deserialize_method($($deserialize_param,)* FieldVisitor) + } + } + + struct StructVisitor; + + impl<'de> Visitor<'de> for StructVisitor { + type Value = Struct; + + // GRCOV_EXCL_START + fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fmt.write_str("a struct") + } + // GRCOV_EXCL_STOP + + fn visit_map>(self, mut map: A) + -> Result + { + map.next_key::().map(|_| Struct) + } + } + + #[derive(Debug)] + struct Struct; + + impl<'de> Deserialize<'de> for Struct { + fn deserialize>(deserializer: D) + -> Result + { + deserializer.deserialize_struct("Struct", &[], StructVisitor) + } + } + + assert_eq!( + ron::from_str::("(true: 4)").unwrap_err().code, + ron::Error::ExpectedIdentifier + ) + } + }; +} + +test_non_identifier! { test_bool => deserialize_bool() } +test_non_identifier! { test_i8 => deserialize_i8() } +test_non_identifier! { test_i16 => deserialize_i16() } +test_non_identifier! { test_i32 => deserialize_i32() } +test_non_identifier! { test_i64 => deserialize_i64() } +#[cfg(feature = "integer128")] +test_non_identifier! { test_i128 => deserialize_i128() } +test_non_identifier! { test_u8 => deserialize_u8() } +test_non_identifier! { test_u16 => deserialize_u16() } +test_non_identifier! { test_u32 => deserialize_u32() } +test_non_identifier! { test_u64 => deserialize_u64() } +#[cfg(feature = "integer128")] +test_non_identifier! { test_u128 => deserialize_u128() } +test_non_identifier! { test_f32 => deserialize_f32() } +test_non_identifier! { test_f64 => deserialize_f64() } +test_non_identifier! { test_char => deserialize_char() } +test_non_identifier! { test_string => deserialize_string() } +test_non_identifier! { test_bytes => deserialize_bytes() } +test_non_identifier! { test_byte_buf => deserialize_byte_buf() } +test_non_identifier! { test_option => deserialize_option() } +test_non_identifier! { test_unit => deserialize_unit() } +test_non_identifier! { test_unit_struct => deserialize_unit_struct("") } +test_non_identifier! { test_newtype_struct => deserialize_newtype_struct("") } +test_non_identifier! { test_seq => deserialize_seq() } +test_non_identifier! { test_tuple => deserialize_tuple(0) } +test_non_identifier! { test_tuple_struct => deserialize_tuple_struct("", 0) } +test_non_identifier! { test_map => deserialize_map() } +test_non_identifier! { test_struct => deserialize_struct("", &[]) } +test_non_identifier! { test_enum => deserialize_enum("", &[]) }