【问题标题】:How can I serialize multiple vectors into a single sequence with serde?如何使用 serde 将多个向量序列化为一个序列?
【发布时间】:2023-01-08 02:00:52
【问题描述】:

尝试将两个不同的 Vec 字段序列化为 JSON 输出中的单个数组。我不知道如何实现 serialize() 方法:

struct Base<'a> {
    workspace: Vec<Workspace<'a>>,
    methods: Vec<Request<'a>>,
    // other fields ...
}

impl Serialize for Base<'_> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut state = serializer.serialize_struct("Base", 5)?;

        state.serialize_field("resources", &self.methods)?;
        state.serialize_field("resources", &self.workspace)?;
        // other fields ...

        state.end()
    }
}

我想将 workspacemethods 字段一起序列化,但是最后一个 "resources" 字段会覆盖第一个字段。我尝试使用类似这样的方法解决它,但它会产生错误,因为 serializer 移动:

let mut resources = serializer.serialize_seq(Some(self.workspace.len() + self.methods.len()))?;

self.workspace.iter().for_each(|f| { resources.serialize_element(f); });
self.methods.iter().for_each(|f| { resources.serialize_element(f); });

resources.end();

那我怎么把这两个联系在一起呢?

【问题讨论】:

  • 您希望您的输出看起来如何?比如说你有一个Base { workspace: vec![0, 2], methods: vec![1, 3] },你想要"resources": [0,1,2,3]还是"resources": [[0,2], [1,3]]还是"resources": [{"workspace": 0, "methods": 1},{"workspace": 2, "methods": 3}]

标签: json rust serde serde-json


【解决方案1】:

最简单的方法是将您的数据转换为 Rust/serde 等效于序列化函数中您想要的任何 JSON 结构:

// in fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
// Declare whatever structs you need to make the required shape
#[derive(Serialize)]
struct WM {
    workspace: Workspace,
    method: Request,
}
state.serialize_field(
    "resources",
    &self
        .methods
        .iter()
        .zip(self.workspace.iter())
        .map(|(&method, &workspace)| WM { workspace, method })
        .collect::<Vec<_>>(),
)?;

Playground

但是,这将创建一个额外的分配。如果你以某种方式超级热衷于速度或内存使用,你可以不用

state.serialize_field("resources", &ConcatSerializer(&self.workspace, &self.methods))?;
struct ConcatSerializer<'a>(&'a [Workspace], &'a [Request]);
impl<'a> Serialize for ConcatSerializer<'a> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut state = serializer.serialize_seq(Some(self.0.len() + self.1.len()))?;
        for a in self.0 {
            state.serialize_element(a)?;
        }
        for b in self.1 {
            state.serialize_element(b)?;
        }
        state.end()
    }
}

Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2023-02-22
    • 2020-10-17
    • 1970-01-01
    相关资源
    最近更新 更多