Skip to content

Commit

Permalink
Fix newtype variant unwrapping inside enum, seq and map
Browse files Browse the repository at this point in the history
  • Loading branch information
juntyr committed Oct 29, 2021
1 parent 4519973 commit 3995c5c
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,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()?;
Expand Down Expand Up @@ -469,6 +471,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()?;
Expand Down Expand Up @@ -524,6 +528,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))
}

Expand Down
98 changes: 98 additions & 0 deletions tests/250_variant_newtypes.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use ron::{de::from_str, error::ErrorCode};
use serde::Deserialize;

Expand All @@ -13,6 +15,9 @@ enum TestEnum {
TupleNewtypeTupleStruct(TupleStruct),
TupleNewtypeStruct(Struct),
TupleNewtypeEnum(Enum),
TupleNewtypeOption(Option<Struct>),
TupleNewtypeSeq(Vec<Struct>),
TupleNewtypeMap(HashMap<u32, Struct>),
}

#[derive(Debug, Deserialize, Eq, PartialEq)]
Expand All @@ -34,6 +39,8 @@ struct Struct {
enum Enum {
A,
B(Struct),
C(u32, bool),
D { a: u32, b: bool },
}

#[test]
Expand Down Expand Up @@ -181,4 +188,95 @@ fn test_deserialise_tuple_newtypes() {
.unwrap(),
TestEnum::TupleNewtypeEnum(Enum::B(Struct { a: 4, b: false })),
);
assert_eq!(
from_str::<TestEnum>(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(C 4, false)"#)
.unwrap_err()
.code,
ErrorCode::ExpectedArray,
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(C(4, false))"#
)
.unwrap(),
TestEnum::TupleNewtypeEnum(Enum::C(4, false)),
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(D a: 4, b: false)"#
)
.unwrap_err()
.code,
ErrorCode::ExpectedStruct,
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeEnum(D(a: 4, b: false))"#
)
.unwrap(),
TestEnum::TupleNewtypeEnum(Enum::D { a: 4, b: false }),
);

assert_eq!(
from_str::<TestEnum>(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(None)"#)
.unwrap(),
TestEnum::TupleNewtypeOption(None),
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(Some(a: 4, b: false))"#
)
.unwrap(),
TestEnum::TupleNewtypeOption(Some(Struct { a: 4, b: false })),
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeOption(a: 4, b: false)"#
)
.unwrap_err()
.code,
ErrorCode::ExpectedOption,
);
assert_eq!(
from_str::<TestEnum>(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::<TestEnum>(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([])"#).unwrap(),
TestEnum::TupleNewtypeSeq(vec![]),
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([(a: 4, b: false)])"#
)
.unwrap(),
TestEnum::TupleNewtypeSeq(vec![Struct { a: 4, b: false }]),
);
assert_eq!(
from_str::<TestEnum>(
r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeSeq([Struct(a: 4, b: false)])"#
)
.unwrap(),
TestEnum::TupleNewtypeSeq(vec![Struct { a: 4, b: false }]),
);

assert_eq!(
from_str::<TestEnum>(r#"#![enable(unwrap_variant_newtypes)] TupleNewtypeMap({})"#).unwrap(),
TestEnum::TupleNewtypeMap(vec![].into_iter().collect()),
);
assert_eq!(
from_str::<TestEnum>(
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::<TestEnum>(
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()),
);
}

0 comments on commit 3995c5c

Please sign in to comment.