Search code examples
enumsrustvariantserde

How do I use serde to deserialize into a specific enum variant?


I have an enum defined as:

enum Foo {
    Bar { x: i32, y: i32 },
    ... // many more variants
}

Given a JSON string {"x": 5, "y": 7} how would I deserialize explicitly to Foo::Bar {x: 5, y: 7}?

Ideally I would be able to call into the deserializer for a particular variant, i.e. Foo::Bar in my example, rather than resort to something like #[serde(untagged)] which is a poor fit when you know in advance which variant to use.

I could define Bar as a type in its own right but since it's only ever used in the context of Foo, it doesn't seem like the most elegant and/or succinct solution.


Solution

  • You should define Bar as a type in its own right:

    #[derive(Debug, serde::Deserialize)]
    enum Foo {
        Bar(Bar),
        Baz,
    }
    
    #[derive(Debug, serde::Deserialize)]
    struct Bar {
        x: i32,
        y: i32,
    }
    
    fn main() -> serde_json::Result<()> {
        let bar = serde_json::from_str::<Bar>(r#"{"x": 5, "y": 7}"#)?;
        println!("{:?}", bar);
        Ok(())
    }