rust - 使用 "Serde"反序列化时可以映射类型吗?

标签 rust deserialization serde

基本上我有以下数据结构:

enum Value {
    Scalar(f64),
    Vector3((f64, f64, f64)),
}

struct Data {
    attribute: Value,
}
使用 serde 进行序列化/serde_json给出以下
{
    "attribute": { "Scalar": 1.0 }  
}
{
    "attribute": { "Vector3": [ 1.0, 2.0, 3.0 ] }
}
反序列化按预期工作。但是,是否可以将以下内容反序列化为相同的数据结构?
{
    "attribute": 1.0  
}
{
    "attribute": [ 1.0, 2.0, 3.0 ]
}
是否可以“映射”f64Scalar(f64)Vec<f64>Vector3((f64, f64, f64)) ?

两种形式都应该有效。如果以下最小示例有效,那就太好了:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
enum Value {
    Scalar(f64),
    Vector3((f64, f64, f64)),
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
struct Data {
    attribute: Value,
}

fn main() {
    let js1 = r#"
    {
        "attribute": { "Scalar": 1.0 }  
    }"#;
    let d1: Data = serde_json::from_str(js1).unwrap();
    println!("{:?}", d1);

    let js2 = r#"
    {
        "attribute": { "Vector3": [ 1.0, 2.0, 3.0 ] }
    }"#;
    let d2: Data = serde_json::from_str(js2).unwrap();
    println!("{:?}", d2);

    let js3 = r#"
    {
        "attribute": 1.0  
    }"#;
    let d3: serde_json::Result<Data> = serde_json::from_str(js3);
    match d3 {
        Ok(d3) => println!("{:?}", d3),
        Err(e) => println!("{:?}", e),
    }

    let js4 = r#"
    {
        "attribute": [ 1.0, 2.0, 3.0 ] 
    }"#;
    let d4: serde_json::Result<Data> = serde_json::from_str(js4);
    match d4 {
        Ok(d4) => println!("{:?}", d4),
        Err(e) => println!("{:?}", e),
    }
}
输出:
Data { attribute: Scalar(1.0) }
Data { attribute: Vector3((1.0, 2.0, 3.0)) }
Error("expected value", line: 3, column: 22)
Error("expected value", line: 3, column: 22)

最佳答案

您可以使用 #[serde(untagged)]在您的枚举上允许它被“映射”。塞尔德 doesn't currently support两者同时但有一个 hack here虽然我没试过。您还可以在变体中使用带有标记名称的枚举
例子:

#[serde(untagged)]
enum Value {
    Scalar(f64),
    ScalarTagged {Scalar: f64},
    Vector3((f64, f64, f64)),
    Vector3Tagged {
        Vector3: (f64, f64, f64)
    }
}

这通过了您的最小示例

关于rust - 使用 "Serde"反序列化时可以映射类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66611645/

相关文章:

for-loop - 如何从 Rust 中的 for 循环中迭代和提取值

rust - 打印!错误 : expected a literal/format argument must be a string literal

rust - Rust 中是否有一个特性允许在没有协程等实验性功能的情况下按组进行折叠?

java - 在 Java 中如何将 String 转换为 List<ClassName>?

json - 无法将 json 数据反序列化为结构

rust - 如何将对象数组传递给 WebAssembly 并使用 wasm-bindgen 将其转换为结构向量?

rust - 为什么一个特征没有为一个明确实现的类型实现?

intellij-idea - Intellij 报告 Rust 工具链未安装,即使我刚刚安装了它

java - Spring Data Redis 支持 Externalizable 吗?

rust - 当 Foobar 只有一个字段时,直接反序列化一个 Vec<Foobar<T>> 为 Vec<T>