From 8702566c4c23331a69710bcfc02651c9b06bb434 Mon Sep 17 00:00:00 2001 From: Momo Langenstein Date: Fri, 29 Oct 2021 17:39:00 +0000 Subject: [PATCH 1/2] Fix newtype variant unwrapping inside enum, seq and map --- src/de/mod.rs | 10 ++++ tests/250_variant_newtypes.rs | 98 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/de/mod.rs b/src/de/mod.rs index af355b8b8..f3da9cd59 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -129,6 +129,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { + // Newtype variants can only be unwrapped if we receive information + // about the wrapped type - with `deserialize_any` we don't + self.newtype_variant = false; + if self.bytes.consume_ident("true") { return visitor.visit_bool(true); } else if self.bytes.consume_ident("false") { @@ -414,6 +418,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { + self.newtype_variant = false; + if self.bytes.consume("[") { let value = visitor.visit_seq(CommaSeparated::new(b']', &mut self))?; self.bytes.comma()?; @@ -469,6 +475,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { + self.newtype_variant = false; + if self.bytes.consume("{") { let value = visitor.visit_map(CommaSeparated::new(b'}', &mut self))?; self.bytes.comma()?; @@ -524,6 +532,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { + self.newtype_variant = false; + visitor.visit_enum(Enum::new(self)) } diff --git a/tests/250_variant_newtypes.rs b/tests/250_variant_newtypes.rs index 65c339f5f..1eca2dd94 100644 --- a/tests/250_variant_newtypes.rs +++ b/tests/250_variant_newtypes.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use ron::{de::from_str, error::ErrorCode}; use serde::Deserialize; @@ -13,6 +15,9 @@ enum TestEnum { TupleNewtypeTupleStruct(TupleStruct), TupleNewtypeStruct(Struct), TupleNewtypeEnum(Enum), + TupleNewtypeOption(Option), + TupleNewtypeSeq(Vec), + TupleNewtypeMap(HashMap), } #[derive(Debug, Deserialize, Eq, PartialEq)] @@ -34,6 +39,8 @@ struct Struct { enum Enum { A, B(Struct), + C(u32, bool), + D { a: u32, b: bool }, } #[test] @@ -181,4 +188,95 @@ fn test_deserialise_tuple_newtypes() { .unwrap(), TestEnum::TupleNewtypeEnum(Enum::B(Struct { a: 4, b: false })), ); + assert_eq!( + from_str::(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(C 4, false)"#) + .unwrap_err() + .code, + ErrorCode::ExpectedArray, + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(C(4, false))"# + ) + .unwrap(), + TestEnum::TupleNewtypeEnum(Enum::C(4, false)), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(D a: 4, b: false)"# + ) + .unwrap_err() + .code, + ErrorCode::ExpectedStruct, + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(D(a: 4, b: false))"# + ) + .unwrap(), + TestEnum::TupleNewtypeEnum(Enum::D { a: 4, b: false }), + ); + + assert_eq!( + from_str::(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(None)"#) + .unwrap(), + TestEnum::TupleNewtypeOption(None), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(Some(a: 4, b: false))"# + ) + .unwrap(), + TestEnum::TupleNewtypeOption(Some(Struct { a: 4, b: false })), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(a: 4, b: false)"# + ) + .unwrap_err() + .code, + ErrorCode::ExpectedOption, + ); + assert_eq!( + from_str::(r#"#![enable(unwrap_variant_newtypes, implicit_some)] TupleNewtypeOption(a: 4, b: false)"#).unwrap(), + TestEnum::TupleNewtypeOption(Some(Struct { a: 4, b: false })), + ); + + assert_eq!( + from_str::(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([])"#).unwrap(), + TestEnum::TupleNewtypeSeq(vec![]), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([(a: 4, b: false)])"# + ) + .unwrap(), + TestEnum::TupleNewtypeSeq(vec![Struct { a: 4, b: false }]), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([Struct(a: 4, b: false)])"# + ) + .unwrap(), + TestEnum::TupleNewtypeSeq(vec![Struct { a: 4, b: false }]), + ); + + assert_eq!( + from_str::(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeMap({})"#).unwrap(), + TestEnum::TupleNewtypeMap(vec![].into_iter().collect()), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeMap({2: (a: 4, b: false)})"# + ) + .unwrap(), + TestEnum::TupleNewtypeMap(vec![(2, Struct { a: 4, b: false })].into_iter().collect()), + ); + assert_eq!( + from_str::( + r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeMap({8: Struct(a: 4, b: false)})"# + ) + .unwrap(), + TestEnum::TupleNewtypeMap(vec![(8, Struct { a: 4, b: false })].into_iter().collect()), + ); } From c9b7582767385c5bc5e73b3ea8e97ea0a83f7b9c Mon Sep 17 00:00:00 2001 From: Momo Langenstein Date: Tue, 2 Nov 2021 10:07:09 +0000 Subject: [PATCH 2/2] Added Changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d422cca52..8036a6407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - Add `struct_names` option to `PrettyConfig` +- Fix newtype variant unwrapping around enum, seq and map ([#331](https://github.com/ron-rs/ron/pull/331)) ## [0.7.0] - 2021-10-22