- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有两个结构,我想使用标记作为 JSON 中的 "type"
字段进行序列化/反序列化,就像这样。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingA {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingB {
value: usize,
}
这些按预期序列化。例如,
let a = ThingA { value: 0 };
println!("{}", serde_json::to_string(&a)?);
// This yields the expected result:
// {"type":"ThingA","value":0}
但是,当我尝试添加一个枚举作为结构的联合类型时,我遇到了麻烦。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
上面的定义适用于反序列化 JSON,但在序列化期间添加了一个额外的字段。
let json = r#"{"type": "ThingB", "value": 0}"#;
let thing: Thing = serde_json::from_str(json)?;
// Correctly parses to:
// ThingB(ThingB { value: 0 })
println!("{}", serde_json::to_string(&thing)?);
// Incorrectly serializes with an extra "type" field:
// {"type":"ThingB","type":"ThingB","value":0}
将 Thing
枚举上的 #[serde(tag = "type")]
更改为 #[serde(untagged)]
会导致相反的问题:Thing
实例正确序列化,但不再正确解析。
我的目标是让 JSON {"type": "ThingB", value: 0}
评估为 Thing::ThingB(ThingB {value: 0})
在反序列化期间,反之亦然,但前提是我反序列化为 Thing
。如果我有一个未包装的 ThingB
,比如 ThingB {value: 0}
,我希望它序列化为 {"type": "ThingB", value: 0
也是。
所以我的问题是:是否有任何方法可以分配 serde tag
或 untagged
属性,以便它们仅在序列化/反序列化期间应用(类似于 serde 的 重命名
)?如果没有,关于如何实现 Serialize
和/或 Deserialize
以实现我的目标有什么建议吗?
最佳答案
你可以在你的 Thing
枚举中使用 tag
,其他的保持干净:
use serde::{Serialize, Deserialize}; // 1.0.124
use serde_json; // 1.0.64
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ThingA {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ThingB {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
fn main() {
let json = r#"{"type": "ThingB", "value": 0}"#;
let thing: Thing = serde_json::from_str(json).unwrap();
println!("{}", serde_json::to_string(&thing).unwrap());
}
按照评论中的要求。如果我们想要同时标记(枚举和结构),我们需要制作一些 serde
咒语来玩包装器和 with
。可以找到更多信息 here
关于rust - 如何将 serde_json 与联合类型(如枚举)一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66964692/
存在生命周期和 serde::deserialize 问题。尝试阅读错误消息并尝试实现反序列化,但随后出现错误,我需要实现反序列化。 没有生命周期,它可以工作 use serde::{ Deseria
我有一些来自外部 API 的 json,我想输入。数据的形状如下所示: { "summary": { "field1": "foo", "field2": "bar", },
所以我有一个来自某处的 serde Value,我想在之后反序列化之前向 Value 添加额外的“字段”。我正在查看文档,但不知道该怎么做。 更具体地说,假设我有一个 HashMap,我想将其值合并到
我希望能够序列化 Vec作为 JSON(和其他基于 UTF-8 的格式)的 base64 编码字符串,同时保留二进制序列化格式的字节数组。 #[derive(Serialize, Deserializ
我写了一个测试用例: use serde::{Serialize, Deserialize}; use std::collections::BTreeMap; use std::fmt; #[deri
我的意思是,如果 2 个对象在某些属性上重叠,是否有办法尝试匹配 全部 其中? 例如: use serde::{Serialize, Deserialize}; use serde_json; //
我有一个用例,需要将 JSON 反序列化为“远程”(在另一个 crate 中定义)结构的映射。我在这方面经历了一段可笑的困难时期,所以我一定错过了一些明显的东西。 以下本质上是所需的最终状态: use
我正在尝试从具有以下维度的 Rust 文件中读取 JSON: { "DIPLOBLASTIC":"Characterizing the ovum when it has two primary
我有一个用例,需要将 JSON 反序列化为“远程”(在另一个 crate 中定义)结构的映射。我在这方面经历了一段可笑的困难时期,所以我一定错过了一些明显的东西。 以下本质上是所需的最终状态: use
我正在尝试从具有以下维度的 Rust 文件中读取 JSON: { "DIPLOBLASTIC":"Characterizing the ovum when it has two primary
在我的程序开始时,我从一个文件中读取数据: let file = std::fs::File::open("data/games.json").unwrap(); let data: Games =
#[serde(rename)] 似乎是正确的选择,但文档没有说明是否可行或如何操作。 这个 JSON 对象: { "name" : "myobject" "info" : {
我想将第 3 方库枚举与 JSON 相互转换。因为我不想编辑第 3 方源代码,所以我不想使用派生宏。 我想手写serde_json deserialize 方法。我认为模式匹配是可行的方法,但我需要匹
我被困在看似简单的问题上。我明白为什么我看到错误但似乎无法解决它。显然我遗漏了一些基本的东西。 fn terraform_deploy_info(app: &'a MyApp) -> std::res
我卡住了,下面是我收到的 JSON: { "BCH": { "aclass": "currency", "altname": "BCH", "decimals
我试图在 Rust 中 drain() 一个 vec 并将结果编码为 JSON 字符串。执行此操作的最佳惯用方法是什么? #![feature(custom_derive, plugin)] #![p
#[serde(rename)] 似乎是正确的选择,但文档没有说明是否可行或如何操作。 这个 JSON 对象: { "name" : "myobject" "info" : {
运行代码时: #![allow(unused)] use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std
我有一个包含类型 Option 的字段的结构体 我希望能够在该字段中存储任何对象(即由任何结构创建的对象)。我目前使用的方法是首先将对象转换为 JSON 字符串(使用 serde_json::to_s
extern crate serde_json; use serde_json::Value; use std::fs::File; use std::io::prelude::*; fn main(
我是一名优秀的程序员,十分优秀!