Can Serde deserialize JSON to one of a set of types depending on the value of a field?

后端 未结 1 1429
盖世英雄少女心
盖世英雄少女心 2020-12-20 18:37

I have a group of different messages that come in as JSON and can be distinguished based on a single field, but then each variant has a different collection of secondary fie

相关标签:
1条回答
  • 2020-12-20 18:46

    There is no point to keep "one" or "two" in your structure MessageOne and MessageTwo: if you have constructed this structure you already know if it is message one or message two.

    extern crate serde; // 1.0.78
    extern crate serde_json; // 1.0.27
    
    #[macro_use]
    extern crate serde_derive;
    
    #[derive(Serialize, Deserialize, Debug)]
    #[serde(tag = "op")]
    enum Message {
        #[serde(rename = "one")]
        One { x: f64, y: f64 },
        #[serde(rename = "two")]
        Two { a: f64, b: f64 },
    }
    
    fn process_message(message: &Message) {
        println!("Processing a : {:?}", message);
    }
    
    use serde_json::Error;
    
    fn main() -> Result<(), Error> {
        let data = r#"{
            "op": "one",
            "x": 1.0,
            "y": 2.0
        }"#;
    
        let message: Message = serde_json::from_str(data)?;
        process_message(&message);
    
        let data = r#"{
            "op": "two",
            "a": 1.0,
            "b": 2.0
        }"#;
    
        let message: Message = serde_json::from_str(data)?;
        process_message(&message);
    
        let data = r#"{
            "op": "42",
            "i": 1.0,
            "j": 2.0
        }"#;
    
        let message: Message = serde_json::from_str(data)?;
        process_message(&message);
        Ok(())
    }
    
    Standard Output
    Processing a : One { x: 1.0, y: 2.0 }
    Processing a : Two { a: 1.0, b: 2.0 }
    
    Standard Error
    Error: Error("unknown variant `42`, expected `one` or `two`", line: 2, column: 18)
    
    0 讨论(0)
提交回复
热议问题