我有一个
Vec<Foo>
,我想将其序列化为包含多个 YAML 文档的单个 YAML 文件,用 ---
分隔,如下所示:
foo_key: foo_value
other_key: 123
other_other_key: []
---
foo_key: bar_value
other_key: 312
other_other_key: [other_item]
---
foo_key: baz_value
other_key: 123321
other_other_key: [item]
这可能吗?我知道我可以使用以下代码片段将上述文件反序列化为
Vec<Foo>
:
#[derive(Debug, Deserialize, Serialize)]
struct Foo {
foo_key: String,
other_key: String,
other_other_key: Vec<String>,
}
let foos: Vec<Foo> = serde_yaml::Deserializer::from_str(&yaml_file)
.filter_map(|doc| Foo::deserialize(doc).ok())
.collect();
但我不知道如何序列化
Vec<Foo>
。
编辑:我宁愿不使用
---
连接每个 YAML 文档,这似乎与使用序列化 YAML 的库背道而驰:
let serialised_foo_documents = foos
.into_iter()
.filter_map(|foo| serde_yaml::to_string(&foo).ok())
.reduce(|acc, e| acc + "---\n" + &e)
.unwrap_or_default();
这可以与反序列化非常相似地完成:
let mut serializer = serde_yaml::Serializer::new(Vec::new());
for foo in &foos {
foo.serialize(&mut serializer).unwrap();
}
let s = String::from_utf8(serializer.into_inner()).unwrap();
println!("{s}");
这相当简单,只需重复使用相同的
serde_yaml::Serializer
,就像文档向您展示的那样:
use anyhow::Result; use serde::Serialize; use std::collections::BTreeMap; fn main() -> Result<()> { let mut buffer = Vec::new(); let mut ser = serde_yaml::Serializer::new(&mut buffer); let mut object = BTreeMap::new(); object.insert("k", 107); object.serialize(&mut ser)?; object.insert("J", 74); object.serialize(&mut ser)?; assert_eq!(buffer, b"k: 107\n---\nJ: 74\nk: 107\n"); Ok(()) }
所以对于你的
Vec<Foo>
来说就是:
for foo in &foos {
foo.serialize(&mut ser)?;
}