[SOLVED] Serde JSON deserializing enums

Issue

This Content is from Stack Overflow. Question asked by dudebro

I have an enum:

#[derive(Serialize, Deserialize)]
enum Action {
    Join,
    Leave,
}

and a struct:

#[derive(Serialize, Deserialize)]
struct Message {
    action: Action,
}

and I pass a JSON string:

"{"action":0}" // `json_string` var

but when I try deserialzing this like this:

let msg: Message = serde_json::from_str(json_string)?;

I get the error expected value at line 1 column 11.

In the JSON if I were to replace the number 0 with the string "Join" it works, but I want the number to correspond to the Action enum’s values (0 is Action::Join, 1 is Action::Leave) since its coming from a TypeScript request. Is there a simple way to achieve this?



Solution

You want serde_repr!

Here’s example code from the library’s README:

use serde_repr::{Serialize_repr, Deserialize_repr};

#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
enum SmallPrime {
    Two = 2,
    Three = 3,
    Five = 5,
    Seven = 7,
}

fn main() -> serde_json::Result<()> {
    let j = serde_json::to_string(&SmallPrime::Seven)?;
    assert_eq!(j, "7");

    let p: SmallPrime = serde_json::from_str("2")?;
    assert_eq!(p, SmallPrime::Two);

    Ok(())
}

For your case:

use serde_repr::{Serialize_repr, Deserialize_repr};

#[derive(Serialize_repr, Deserialize_repr)]
#[repr(u8)]
enum Action {
    Join = 0,
    Leave = 1,
}

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Message {
    action: Action,
}


This Question was asked in StackOverflow by dudebro and Answered by wisha It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?