Skip to content

Commit 623baf1

Browse files
authored
Merge pull request #12 from spyoungtech/gh-11
gh-11 fix enum unit variant behavior
2 parents 283c076 + 3ba7691 commit 623baf1

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

src/de.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -362,21 +362,19 @@ impl<'de, 'a> Deserializer<'de> for JSONValueDeserializer<'a> {
362362
// in user code.
363363
use serde::de::IntoDeserializer;
364364
match self.input {
365-
JSONValue::Identifier(ident) => {
365+
JSONValue::Identifier(ident) | JSONValue::SingleQuotedString(ident) | JSONValue::DoubleQuotedString(ident) => {
366366
// We'll treat the entire enum as a single variant with no payload:
367367
visitor.visit_enum(ident.into_deserializer())
368368
}
369369
JSONValue::JSONObject { key_value_pairs } if !key_value_pairs.is_empty() => {
370370
// Possibly the first key is your variant, the value is the data.
371371
// Example pattern for `Tag: { /* contents */ }` style
372372
let kv = &key_value_pairs[0];
373-
if let JSONValue::Identifier(ref variant) = kv.key {
374-
visitor.visit_enum(EnumDeserializer {
375-
variant,
376-
content: &kv.value,
377-
})
378-
} else {
379-
Err(de::Error::custom("Invalid enum representation"))
373+
match kv.key {
374+
JSONValue::Identifier(variant) | JSONValue::SingleQuotedString(variant) | JSONValue::DoubleQuotedString(variant) => {
375+
visitor.visit_enum(EnumDeserializer {variant, content: &kv.value})
376+
}
377+
_ => Err(de::Error::custom("Invalid enum representation"))
380378
}
381379
}
382380
_ => Err(de::Error::custom("Unsupported enum representation")),
@@ -488,7 +486,13 @@ impl<'de, 'a> VariantAccess<'de> for JSONValueDeserializer<'a> {
488486

489487
fn unit_variant(self) -> Result<(), Self::Error> {
490488
// If the variant is expected to have no value, do nothing:
491-
Ok(())
489+
match self.input {
490+
JSONValue::Null => {Ok(())}
491+
_ => {
492+
Err(de::Error::custom("Unit variants must be null"))
493+
}
494+
}
495+
492496
}
493497

494498
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
@@ -636,7 +640,7 @@ mod test {
636640
mod json5_compat_tests {
637641
use super::*; // Bring in your `from_str` parser.
638642
use std::collections::BTreeMap; // Or HashMap, if preferred.
639-
use serde::Deserialize;
643+
use serde::{Deserialize, Serialize};
640644

641645
/// A minimal JSON5-like "value" type for testing.
642646
/// Adjust as needed for your parser’s feature set.
@@ -1166,4 +1170,34 @@ mod json5_compat_tests {
11661170
_ => panic!("Expected empty object after whitespace"),
11671171
}
11681172
}
1173+
1174+
#[test]
1175+
fn test_gh_11() {
1176+
use crate::from_str;
1177+
#[derive(Debug, Clone, serde::Deserialize, Serialize, PartialEq)]
1178+
#[serde(rename_all="snake_case")]
1179+
enum SomeEnum{
1180+
VariantA(String),
1181+
VariantB,
1182+
}
1183+
1184+
#[derive(Debug, Clone, serde::Deserialize, Serialize)]
1185+
struct SomeStruct {
1186+
some_enum: SomeEnum
1187+
}
1188+
1189+
1190+
let json5 = r#"{some_enum: "variant_b" }"#;
1191+
let parsed: SomeStruct = from_str(json5).unwrap();
1192+
assert_eq!(parsed.some_enum, SomeEnum::VariantB);
1193+
1194+
let json5 = r#"{some_enum: {"variant_b": null} }"#;
1195+
let parsed: SomeStruct = from_str(json5).unwrap();
1196+
assert_eq!(parsed.some_enum, SomeEnum::VariantB);
1197+
1198+
1199+
let json5 = r#"{some_enum: { "variant_b": {} }}"#;
1200+
let maybe_res: Result<SomeStruct, _> = from_str(json5);
1201+
let err = maybe_res.unwrap_err();
1202+
}
11691203
}

0 commit comments

Comments
 (0)