1

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.

malthe
  • 1,237
  • 13
  • 25
  • 1
    If you know for sure you are going to have a `Foo::Bar`, why use the enum in the first place rather than making `Bar` a type on its own? – mcarton Dec 23 '19 at 19:49
  • The enum represents an HTTP request message or _route_. I know from the path which message to create. In the example, `Bar` represents a particular route and the struct might then be deserialized from the HTTP request body. – malthe Dec 23 '19 at 20:40

1 Answers1

2

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(())
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366