rust 如何反序列化嵌套结构?

efzxgjgh  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(150)

假设应该读取以下JSON:

let json = r#"{
    "scjson": [
        { "StateMachine": { "id": "sm_1" } },
        { "StateMachine": { "id": "sm_2" } }
    ]
}"#;

换句话说:一个状态机数组,每个状态机都有一个字符串类型的字段“id”。
我怎么用serde反序列化这个呢?我试过:

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StateMachine {
    id: String,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Scjson {
    scjson: Vec<StateMachine>,
}

但ID永远不会反序列化。
最后,我想解析一下:

scjson:
  - StateMachine:
      id: "sm_1"
      states:
        - AtomicState:
            id: atomic_1
        - AtomicState:
            id: atomic_2
            transitions:
              - Transition: { event: "E1", executable_content: "asdf" }
        - ParallelState:
            InitialTransition: { }
        - CompoundState:
            id: compound_1
            initialTransition: { event: "E2", condition: "some condition" }
  - StateMachine:
      id: "sm_2"
      states:
        - FinalState:
            id: "asdf"
            onEntry: "17"
62o28rlo

62o28rlo1#

缺少一层间接寻址。scjson键包含一个YAML字典列表,其中每个字典都有一个键StateMachine,其值是另一个字典,该字典只有一个键id
以下是固定版本:

use serde::{Deserialize, Serialize};
use serde_yaml;

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StateMachine {
    id: String,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Scjson {
    scjson: Vec<ScjsonElement>,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct ScjsonElement {
    StateMachine: StateMachine,
}

fn main() {
    let message = r#"
scjson:
  - StateMachine:
      id: "sm_1"
  - StateMachine:
      id: "sm_2"
    "#;

    let result: Scjson = serde_yaml::from_str(message).unwrap();
    println!("{:?}", result)
}

这是一个简单明了的解决方案,但似乎无论生成YAML/JSON的是什么,都会使用StateMachine和类似的键来编码元素类型,如果是这种情况,那么enum就是正确的答案:

use serde::{Deserialize, Serialize};
use serde_yaml;

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StateMachine {
    id: String,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Scjson {
    scjson: Vec<ScjsonElement>,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub enum ScjsonElement {
    StateMachine(StateMachine),
}

fn main() {
    let message = r#"
scjson:
  - StateMachine:
      id: "sm_1"
  - StateMachine:
      id: "sm_2"
    "#;

    let result: Scjson = serde_yaml::from_str(message).unwrap();
    println!("{:?}", result)
}

相关问题