How to remove enum variant name when using serde_json::to_string

My code below return the JSON string as:
{"name":"Test 1","detail":[{"Float":34.0},{"String":"test"}]}
I want it return as
{"name":"Test 1","detail":[34.0, "test"]}
Does anyone know it's possible? Thanks!

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct TestJSON {
    name: String,
    detail: Vec<GenericData>,
}

#[derive(Serialize, Deserialize, Debug)]
enum GenericData {
    Float(f32),
    String(String),
}

fn main() {
    let mut generic_list = Vec::new();
    generic_list.push(GenericData::Float(34.0));
    generic_list.push(GenericData::String(String::from("test")));

    let t = TestJSON {
        name: String::from("Test 1"),
        detail: generic_list,
    };

    let j = serde_json::to_string(&t).unwrap();
    println!("{}", j);
}

Use the #[serde(untagged)] attribute:

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum GenericData {
    Float(f32),
    String(String),
}

(playground)

3 Likes

@mbrubeck, wow, that works great. thanks!

Just a FYI, if you have dynamic data like that, you could use serde_json::Value instead of your own enum. (playground)

1 Like

@erelde, this is a great solution. I tried serde_json::Value before, but was stuck when I tried to initialize float in the code below, it won't compile. wasn't aware I can use serde_json::Value::from instead. thank you!

let mut generic_list = Vec::new();
generic_list.push(serde_json::Value::String(String::from("test")));

generic_list.push(serde_json::Value::Number(Number{n: 34.4}));