Serde: Stringish enum de/serialization

Created on 17 Aug 2017  路  5Comments  路  Source: serde-rs/serde

enum Enum {
    Foo,
    Bar,
    Quux,
    Other(String),
}

I want the de/serialization relation to be:

"foo" <-> Enum::Foo
"bar" <-> Enum::Bar
"quux" <-> Enum::Quux
"other thing" <-> Enum::Other("other thing")
enhancement

Most helpful comment

Yeah, treat this as a feature request for an attribute.

All 5 comments

There isn't an attribute for it but something like this could work:

impl Serialize for Enum {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_str(match *self {
            Enum::Foo => "foo",
            Enum::Bar => "bar",
            Enum::Quux => "quux",
            Enum::Other(ref other) => other,
        })
    }
}

impl<'de> Deserialize<'de> for Enum {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        let s = String::deserialize(deserializer)?;
        Ok(match s.as_str() {
            "foo" => Enum::Foo,
            "bar" => Enum::Bar,
            "quux" => Enum::Quux,
            _ => Enum::Other(s),
        })
    }
}

Yeah, treat this as a feature request for an attribute.

Any progress on this? Its very common to use a string as an enum within JSON APIs (for example), and you'd like to work with a strongly typed enum in rust land.

I would prefer to see this implemented as a separate derive macro in a different crate:

#[derive(Serialize_str, Deserialize_str)]
enum Enum {
    Foo,
    Bar,
    Quux,
    Other(String),
}

for people searching a solution @dtolnay actually programmed a solution:
https://github.com/dtolnay/serde-repr

Was this page helpful?
0 / 5 - 0 ratings