diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/pot/src/de.rs b/pot/src/de.rs index 7a0fb2e7..d7a71355 100644 --- a/pot/src/de.rs +++ b/pot/src/de.rs @@ -995,23 +995,16 @@ impl<'a, 's, 'de, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'s, ' where V: DeserializeSeed<'de>, { - // Have the seed deserialize the next atom, which should be the symbol. + // Enum variants that have associated data emit a Named atom followed by + // a mapping of the name and associated data. To parse this, we simply + // need to skip the Named atom. let atom = self.peek_atom()?; - match atom.kind { - Kind::Special if matches!(atom.nucleus, Some(Nucleus::Named)) => { - self.read_atom()?; - let val = seed.deserialize(&mut *self)?; - Ok((val, self)) - } - Kind::Symbol => { - let val = seed.deserialize(&mut *self)?; - Ok((val, self)) - } - _ => Err(Error::custom(format!( - "expected Named, got {:?}", - atom.kind - ))), + if atom.kind == Kind::Special && matches!(atom.nucleus, Some(Nucleus::Named)) { + self.read_atom()?; } + + let val = seed.deserialize(&mut *self)?; + Ok((val, self)) } } diff --git a/pot/src/tests.rs b/pot/src/tests.rs index b97ca4d5..89dbf30e 100644 --- a/pot/src/tests.rs +++ b/pot/src/tests.rs @@ -764,3 +764,39 @@ fn backwards_compatible() { let parsed: Canary = crate::from_slice(&v1_canary).unwrap(); assert_eq!(canary, parsed); } + +#[test] +fn unit_enum_fix() { + let test_payload = vec![EnumVariants::Unit, EnumVariants::Tuple(0)]; + let ambiguous = Config::new() + .compatibility(Compatibility::Full) + .serialize(&test_payload) + .unwrap(); + let fixed = Config::new() + .compatibility(Compatibility::V4) + .serialize(&test_payload) + .unwrap(); + assert_ne!(ambiguous, fixed); + + let bad_value: Value<'_> = crate::from_slice(&ambiguous).unwrap(); + let good_value: Value<'_> = crate::from_slice(&fixed).unwrap(); + match bad_value { + Value::Sequence(sequence) => { + assert_eq!(sequence[1], Value::None); + } + other => unreachable!("Unexpected value: {other:?}"), + } + match good_value { + Value::Sequence(sequence) => { + assert_eq!(sequence.len(), 2); + assert_eq!( + sequence[1], + Value::Mappings(vec![( + Value::String(Cow::Borrowed("Tuple")), + Value::from(0_u8) + )]) + ); + } + other => unreachable!("Unexpected value: {other:?}"), + } +}