如何使用 serde 将结构序列化为另一个 Rust 数据结构?
How can I use serde to serialize a struct to another Rust data structure?
我有一个数据结构 Document
,我想将其他 Rust 结构序列化到它。它基本上是内部字段的 HashMap
,但是它与数据库交互 API,所以我肯定想将其他类型转换为那些 Document
s。
例如这个结构
struct Entry {
id: String,
user: String,
duration: u32,
location: (f64, f64),
}
我已经使用 From
特征转换为 Document
类型,但是当 Entry
结构更改时,这是我必须修改的额外位置。该实现使用 DocumentBuilder
并且看起来像这样:
impl From<Entry> for Document {
fn from(entry: Entry) -> Self {
Document::builder()
.name(&entry.id) // set the name of the document
.field("user", entry.user) // add fields ...
.field("duration", entry.duration)
.field("location", entry.location)
.build() // build a Document
}
}
field
方法可以将任何可以转换为 FieldValue
的值分配给键。所以field
的签名是:
impl DocumentBuilder {
// ...
pub fn field<T: Into<FieldValue>>(mut self, key: &str, value: T) -> Self { ... }
// ...
}
我想使用 serde 及其派生功能自动将结构及其字段序列化为 Document
。我该怎么做呢?我在 wiki 上查看了 Implementing a Serializer,但显示的示例写入了一个字符串,我想知道如何使用构建器模式序列化为数据结构。
最简单的方法是使用 serde_json::from_value
(即使您不使用 JSON 也适用,但要求所有字段都有效 JSON [例如,不哈希图中的非字符串键]):
let entry = Entry {
a: 24,
b: 42,
c: "nice".to_string()
};
let v = serde_json::to_value(&entry).unwrap();
let document: Document = serde_json::from_value(v).unwrap();
警告:Document
的值类型必须实现 Deserialize
,并且可以将任何值反序列化为正确的参数。这可以通过使用 #[serde(untagged)]
来完成,但可能容易出现某些类型错误,例如 u8
被转换为 u64
.
一种不涉及任何不必要副本的更复杂的方法将要求您编写自定义(反)序列化程序,一个值得关注的方法是 serde_transcode::transcode
,它执行与你想要的东西 - 它在两种数据格式之间转换。
我有一个数据结构 Document
,我想将其他 Rust 结构序列化到它。它基本上是内部字段的 HashMap
,但是它与数据库交互 API,所以我肯定想将其他类型转换为那些 Document
s。
例如这个结构
struct Entry {
id: String,
user: String,
duration: u32,
location: (f64, f64),
}
我已经使用 From
特征转换为 Document
类型,但是当 Entry
结构更改时,这是我必须修改的额外位置。该实现使用 DocumentBuilder
并且看起来像这样:
impl From<Entry> for Document {
fn from(entry: Entry) -> Self {
Document::builder()
.name(&entry.id) // set the name of the document
.field("user", entry.user) // add fields ...
.field("duration", entry.duration)
.field("location", entry.location)
.build() // build a Document
}
}
field
方法可以将任何可以转换为 FieldValue
的值分配给键。所以field
的签名是:
impl DocumentBuilder {
// ...
pub fn field<T: Into<FieldValue>>(mut self, key: &str, value: T) -> Self { ... }
// ...
}
我想使用 serde 及其派生功能自动将结构及其字段序列化为 Document
。我该怎么做呢?我在 wiki 上查看了 Implementing a Serializer,但显示的示例写入了一个字符串,我想知道如何使用构建器模式序列化为数据结构。
最简单的方法是使用 serde_json::from_value
(即使您不使用 JSON 也适用,但要求所有字段都有效 JSON [例如,不哈希图中的非字符串键]):
let entry = Entry {
a: 24,
b: 42,
c: "nice".to_string()
};
let v = serde_json::to_value(&entry).unwrap();
let document: Document = serde_json::from_value(v).unwrap();
警告:Document
的值类型必须实现 Deserialize
,并且可以将任何值反序列化为正确的参数。这可以通过使用 #[serde(untagged)]
来完成,但可能容易出现某些类型错误,例如 u8
被转换为 u64
.
一种不涉及任何不必要副本的更复杂的方法将要求您编写自定义(反)序列化程序,一个值得关注的方法是 serde_transcode::transcode
,它执行与你想要的东西 - 它在两种数据格式之间转换。