Crates.io | serde_hooks |
lib.rs | serde_hooks |
version | 0.1.1 |
source | src |
created_at | 2023-10-01 15:49:32.37806 |
updated_at | 2023-10-01 16:05:42.483186 |
description | Runtime hooks for serde |
homepage | https://github.com/anatols/serde_hooks |
repository | https://github.com/anatols/serde_hooks |
max_upload_size | |
id | 989293 |
size | 261,381 |
This crate allows you to hook into [serde
] serialization. You can get callbacks for each piece of data that is being serialized, and modify serialization behavior at runtime.
For example, you can, at runtime:
You likely wouldn't.
Seriously, in the vast majority of cases, what [serde
] offers out of the box is enough, and more optimal to use. Before you consider using this crate, please check serde.rs, including the examples section. After that, consider changing your data model in a way that you can use bare serde
. Only then, if none of the above helps, come back for the hooks.
Some examples where having runtime control over serialization can be handy:
salary
field from Employee
struct for everyone but their manager.#[derive(Serialize)]
. Just not exactly with the #[serde]
attributes you want there.Obviously, all of these cases can be handled by either implementing custom serialization, or using something like #[serde(serialize_with = ...)]
. But let's face it, it's not fun: you'd need to type a ton of boilerplate and the default serde
derive is so much nicer to use.
In fact, this crate actually is that ton of boilerplate that just calls back to you at the right moments.
This example shows conditional exclusion of a field at runtime:
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}"#);
More examples are available throughout the documentation and in the repository, in the examples
directory.
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.