You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用serde_yaml将多个文档序列化到同一个文件?

如何将Vec<Foo>序列化为多文档YAML文件?

我需要把一个Vec<Foo>序列化为包含多个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();

但不知道怎么反向序列化,而且我不想通过手动拼接每个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();

解决方案

可以直接使用serde_yaml::Serializer来逐个序列化每个Foo实例,并在文档之间写入分隔符,避免手动拼接字符串:

use serde::{Serialize, Deserialize};
use serde_yaml::{Serializer, SerializerError};
use std::io::Write;

#[derive(Debug, Deserialize, Serialize)]
struct Foo {
    foo_key: String,
    other_key: String,
    other_other_key: Vec<String>,
}

// 将Vec<Foo>序列化为多文档YAML的函数
fn serialize_foos<W: Write>(foos: &[Foo], writer: W) -> Result<(), SerializerError> {
    let mut serializer = Serializer::new(writer);
    let mut is_first_doc = true;

    for foo in foos {
        if !is_first_doc {
            // 非第一个文档前写入分隔符和换行
            serializer.serialize_newline()?;
            serializer.serialize_str("---")?;
            serializer.serialize_newline()?;
        }
        // 序列化当前Foo实例
        foo.serialize(&mut serializer)?;
        is_first_doc = false;
    }

    Ok(())
}

// 使用示例
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let foos = vec![
        Foo {
            foo_key: "foo_value".into(),
            other_key: "123".into(),
            other_other_key: vec![],
        },
        Foo {
            foo_key: "bar_value".into(),
            other_key: "312".into(),
            other_other_key: vec!["other_item".into()],
        },
        Foo {
            foo_key: "baz_value".into(),
            other_key: "123321".into(),
            other_other_key: vec!["item".into()],
        },
    ];

    // 可以将结果写入文件、内存缓冲区等,这里用Vec<u8>作为示例
    let mut buffer = Vec::new();
    serialize_foos(&foos, &mut buffer)?;

    // 输出序列化后的YAML内容
    println!("{}", String::from_utf8(buffer)?);
    Ok(())
}

说明

这个方法直接利用serde_yaml的序列化机制:

  • 创建一个Serializer实例绑定到目标写入器(可以是文件、内存缓冲区等)
  • 遍历Vec<Foo>,第一个文档直接序列化,后续文档先写入---分隔符再序列化
  • 全程由序列化库处理YAML格式的生成,避免手动拼接字符串可能带来的格式错误

内容的提问来源于stack exchange,提问作者beyarkay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:23:23