如何用不同的可能字段名称反序列化?

时间:2019-08-12 17:55:21

标签: rust serde

我正在尝试使用消息列表反序列化一个大JSON文件。消息的内容几乎相同,但是一些消息的字段为“内容”,而其他消息的字段为“照片”,这是不同照片的列表。

当我不知道哪些消息具有哪些字段时,如何反序列化文件?例如,我希望所有包含“内容”字段的消息都变为ContentMessage类型,而所有包含“照片”消息都变为PhotosMessage

messages.json:

{
    "messages": [
        {
            "sender_name": "Ellie",
            "timestamp_ms": 1565429540063,
            "content": "Hi"
        },
        {
            "sender_name": "Ola",
            "timestamp_ms": 1565429535795,
            "photos": [
            {
                "uri": "messages/inbox/photo1.jpg",
                "creation_timestamp": 1565387272
            },
            {
                "uri": "messages/inbox/photo2.jpg",
                "creation_timestamp": 1565387273
            },
            {
                "uri": "messages/inbox/photo3.jpg",
                "creation_timestamp": 1565387273
            }
            ]
        }
    ]
}

main.rs:

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use std::error::Error;
use std::fs::File;
use std::io::Read;


#[derive(Deserialize, Debug)]
struct MessageFile {
    messages: Vec<Message>,
}

#[derive(Deserialize, Debug)]
enum Message {
    ContentMessage,
    PhotosMessage
}

#[derive(Deserialize, Debug)]
struct ContentMessage {
    sender_name: String,
    timestamp_ms: u64,
    content: String
}

#[derive(Deserialize, Debug)]
struct PhotosMessage {
    sender_name: String,
    timestamp_ms: u64,
    photos: Vec<Photo>
}

#[derive(Deserialize, Debug)]
struct Photo {
    uri: String,
    creation_timestamp: u64,
}

fn main() {
    try_main().unwrap();
}

fn try_main() -> Result<(), Box<Error>> {
    // Read the input file to string.
    let mut file = File::open("messages.json")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;

    // Deserialize and print Rust data structure.
    let data: MessageFile = serde_json::from_str(&contents)?;
    println!("{:#?}", data);

    Ok(())
}

使用此代码,我得到一个错误“未知变体sender_name,预期为'ContentMessage'或'PhotosMessage'”。我希望整个邮件能够与其中任何一个类别匹配,而不仅仅是sender_name

0 个答案:

没有答案