5 unstable releases
0.3.0 | Nov 6, 2024 |
---|---|
0.2.0 | Oct 25, 2024 |
0.1.2 | Oct 25, 2024 |
0.1.1 | Oct 24, 2024 |
0.1.0 | Oct 24, 2024 |
#777 in Encoding
31KB
623 lines
diffogus
This crate provides a flexible and customizable framework for computing differences ("diffs")
between various types of data structures in Rust. The core functionality is built around the
traits diff::Diffable
and diff::Changeable
, which allow you to determine changes between two instances
of a type and represent those changes in a structured way.
Overview
The crate supports diffing primitive types (e.g., integers, floats, strings), as well as
collections like HashMap
, Vec
, and Option
. It can be extended to handle custom types
by implementing the diff::Diffable
trait.
The result of a diff
operation can be serialized into formats such as JSON, provided the
serde
feature is enabled.
Traits
diff::Changeable
- A trait for types that can report whether they have changed.diff::Diffable
- A trait for types that can compute a difference with another instance of the same type.
Supported Types
By default, this crate implements diff::Diffable
for most types.
Full list of types:
- Primitive types:
u8
,u16
,u32
,u64
,i8
,i16
,i32
,i64
,f32
,f64
,bool
, andString
. - Collections:
HashMap<K, V>
,Vec<T>
. - Containers:
Option<T>
.
Features
serde
: Enables support for serializing diff results usingserde
.derive
: Enables support forDiff
derive macro.
Usage
Basic Diffing
Here's a simple example that shows how to compute a diff between two integers:
use diffogus::diff::{Diffable, PrimitiveDiff};
let a = 5;
let b = 10;
let diff = a.diff(&b);
match diff {
PrimitiveDiff::Changed { old, new } => {
println!("Value changed from {} to {}", old, new);
},
PrimitiveDiff::Unchanged => {
println!("No change detected.");
}
}
Diffing more complex data structures
You can also compute diffs on more complex structures such as HashMap
or Vec
.
use diffogus::diff::{Diffable, HashMapDiff, CollectionDiffEntry};
use std::collections::HashMap;
let mut map1 = HashMap::new();
map1.insert("key1", 1);
map1.insert("key2", 2);
let mut map2 = HashMap::new();
map2.insert("key1", 1);
map2.insert("key2", 3);
map2.insert("key3", 4);
let diff = map1.diff(&map2);
for (key, diff_entry) in diff.0 {
match diff_entry {
CollectionDiffEntry::Added(new_val) => println!("{} was added with value {}", key, new_val),
CollectionDiffEntry::Removed(old_val) => println!("{} was removed with value {}", key, old_val),
CollectionDiffEntry::Changed(changed_val) => println!("{} changed", key),
CollectionDiffEntry::Unchanged => println!("{} did not change", key),
}
}
Serde Integration
If you want to serialize the diff result (e.g., to JSON), enable the serde
feature:
[dependencies]
diffogus = { version = "0.1", features = ["serde"] }
Example usage:
use diffogus::diff::{Diffable, HashMapDiff};
use serde_json;
use std::collections::HashMap;
let mut map1 = HashMap::new();
map1.insert("key1", 1);
let mut map2 = HashMap::new();
map2.insert("key1", 2);
let diff = map1.diff(&map2);
let serialized = serde_json::to_string(&diff).unwrap();
println!("Serialized diff: {}", serialized);
Derive macro
If you want to implement diff::Diffable
and related traits you can do that very easily by enabling derive
feature:
[dependencies]
diffogus = { version = "0.1", features = ["derive"] }
Example usage:
use diffogus::diff::{Diffable, PrimitiveDiff};
use diffogus_derive::Diff;
#[derive(Debug, Clone, Diff)]
struct MyStruct {
id: u32,
name: String,
}
let a = MyStruct { id: 0, name: "Joe".into() };
let b = MyStruct { id: 0, name: "Doe".into() };
let diff = a.diff(&b);
// Now do whatever you want with this diff.
Dependencies
~0–305KB