Crates.io | serde-diff |
lib.rs | serde-diff |
version | 0.4.1 |
source | src |
created_at | 2019-11-09 10:07:54.818134 |
updated_at | 2021-01-12 10:01:39.79992 |
description | A small helper to serialize the diff of two structs of the same type and apply those differences to other structs. |
homepage | |
repository | https://github.com/amethyst/serde-diff |
max_upload_size | |
id | 179688 |
size | 91,967 |
A small helper that can
The SerdeDiff trait impl can serialize field paths recursively, greatly reducing the amount of data that needs to be serialized when only a small part of a struct/enum has changed.
On a struct or enum:
#[derive(SerdeDiff, Serialize, Deserialize)]
Serialize & apply differences for various formats:
rmp_serde (MessagePack - very small messages)
let msgpack_data = rmp_serde::to_vec_named(&Diff::serializable(&old, &new))?;
let mut deserializer = rmp_serde::Deserializer::new(msgpack_data.as_slice());
Apply::apply(&mut deserializer, &mut target)?;
bincode (very fast serialize/deserialize)
let bincode_data = bincode::serialize(&Diff::serializable(&old, &new))?;
bincode::config().deserialize_seed(Apply::deserializable(&mut target), &bincode_data)?;
serde_json
let json_data = serde_json::to_string(&Diff::serializable(&old, &new))?;
let mut deserializer = serde_json::Deserializer::from_str(&json_data);
Apply::apply(&mut deserializer, &mut target)?;
Cargo.toml
[dependencies]
serde-diff = "0.3"
serde = "1"
serde_json = "1" # all serde formats are supported, serde_json is shown in this example
main.rs
use serde_diff::{Apply, Diff, SerdeDiff};
use serde::{Serialize, Deserialize};
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq, Debug)]
struct TestStruct {
a: u32,
b: f64,
}
fn main() {
let old = TestStruct {
a: 5,
b: 2.,
};
let new = TestStruct {
a: 8, // Differs from old.a, will be serialized
b: 2.,
};
let mut target = TestStruct {
a: 0,
b: 4.,
};
let json_data = serde_json::to_string(&Diff::serializable(&old, &new)).unwrap();
let mut deserializer = serde_json::Deserializer::from_str(&json_data);
Apply::apply(&mut deserializer, &mut target).unwrap();
let result = TestStruct {
a: 8,
b: 4.,
};
assert_eq!(result, target);
}
Opaque structs:
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq)]
#[serde_diff(opaque)] // opaque structs are serialized as a unit and fields do not need to implement SerdeDiff
struct DoesNotRecurse {
value: ExternalType,
}
Opaque fields:
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq)]
struct WrapperStruct {
#[serde_diff(opaque)]
value: ExternalType, // opaque fields only need to implement Serialize + Deserialize + PartialEq,
}
Skip fields:
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq)]
struct WrapperStruct {
#[serde_diff(skip)]
value: ExternalType,
}
Generics:
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq, Debug)]
struct GenericStruct<T>
where
T: SerdeDiff,
{
a: T,
}
Enums:
#[derive(SerdeDiff, Serialize, Deserialize, PartialEq, Debug)]
enum TestEnum {
Structish { x: u32, y: u32 },
Enumish(i32, i32, i32),
Unitish,
}
All contributions are assumed to be dual-licensed under MIT/Apache-2.
Distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT.