Boscop / serde-diff

Utility for comparing two structs and re-applying the differences to other structs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

serde-diff

A small helper that can

  1. Serialize the fields that differ between two structs of the same type
  2. Apply previously serialized field differences to other structs.

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 has changed.

Build Status Crates.io Docs.rs

Status

Works for most basic use-cases. Includes derive macro, some standard library type implementations and deep serde integration. Supports diffing Vec. Supports both text and binary serde formats.

Usage

On a struct:

#[derive(SerdeDiff, Serialize, Deserialize)]

Serialize & apply differences:

bincode

let bincode_data = bincode::serialize(&Diff::serializable(&old, &new)).unwrap();
bincode::config()
        .deserialize_seed(Apply::deserializable(&mut target), &bincode_data)
        .unwrap();

serde_json

        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();

Simple example

Cargo.toml

[dependencies]
serde-diff = "0.1.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);
}

Contribution

All contributions are assumed to be dual-licensed under MIT/Apache-2.

License

Distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT.

About

Utility for comparing two structs and re-applying the differences to other structs

License:Apache License 2.0


Languages

Language:Rust 100.0%