2个版本

0.1.1 2023年10月1日
0.1.0 2023年10月1日

#803 in 编码

MIT/Apache

175KB
3.5K SLoC

Serde Hooks

此crate允许您挂钩到serde序列化。您可以为正在序列化的每份数据获取回调,并在运行时修改序列化行为。

例如,您可以在运行时

  • 重命名或跳过结构体字段。
  • 重命名枚举变体。
  • 替换结构体字段值、映射键和值、序列和元组项。
  • 向映射中添加新条目。
  • 检查序列化的数据结构。

“我为什么需要这个crate?”

你可能不需要。

说真的,在绝大多数情况下,serde提供的开箱即用功能已经足够,并且更优。在考虑使用此crate之前,请检查serde.rs,包括示例部分。然后,考虑以可以使用裸serde的方式更改您的数据模型。只有在此之后,如果上述方法都没有帮助,再回来使用钩子。

一些示例,说明在运行时控制序列化可能很有用

  • 您需要根据权限级别从API响应中排除某些字段。例如,除了经理外,从Employee结构体中排除salary字段。
  • 您需要支持不同格式的不同大小写约定。例如,JSON中的camelCase和YAML中的kebab-case。
  • 您的数据类型来自您无法更改的库,并且已经具有一个#[derive(Serialize)]。只是不是您想要的带有#[serde]属性的那个。

显然,所有这些情况都可以通过实现自定义序列化或者使用类似以下方法进行处理:实现自定义序列化,或者使用 #[serde(serialize_with = ...)]。但说到底,这并不是一件有趣的事情:你需要输入大量的模板代码,而默认的 serde derive 确实更容易使用。

事实上,这个crate实际上就是这些模板代码,它会在合适的时刻调用你。

示例

此示例展示了在运行时条件排除字段的示例

use serde::Serialize;
use serde_hooks::{ser, Path};

#[derive(Serialize)]
struct Employee {
    name: String,
    salary: f64,
}

struct EmployeeHooks {
    boss_is_asking: bool,
}

impl ser::Hooks for EmployeeHooks {
    fn on_struct(&self, path: &Path, st: &mut ser::StructScope) {
        if !self.boss_is_asking {
            st.skip_field("salary");
        }
    }
}

let poor_guy = Employee {
    name: "Richie".into(),
    salary: 1_000_000.99,
};

let json = serde_json::to_string(&ser::hook(
    &poor_guy,
    &EmployeeHooks { boss_is_asking: false }
)).unwrap();
assert_eq!(json, r#"{"name":"Richie"}"#);

let json = serde_json::to_string(&ser::hook(
    &poor_guy,
    &EmployeeHooks { boss_is_asking: true }
)).unwrap();
assert_eq!(json, r#"{"name":"Richie","salary":1000000.99}"#);

更多示例可以在文档和仓库中的 examples 目录中找到。

许可证

根据您的选择,受Apache License,版本2.0或MIT许可证的许可。

除非您明确声明,否则,您根据Apache-2.0许可证定义的任何有意提交以包含在此crate中的贡献,都将按照上述方式双重许可,而无需任何附加条款或条件。

依赖项

~1–1.7MB
~33K SLoC