1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! # 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`, and `String`.
//! - Collections: `HashMap<K, V>`, `Vec<T>`.
//! - Containers: `Option<T>`.
//!
//! ## Features
//!
//! - **`serde`**: Enables support for serializing diff results using `serde`.
//! - **`derive`**: Enables support for [`Diff`] derive macro.
//!
//! ## Usage
//!
//! ### Basic Diffing
//!
//! Here's a simple example that shows how to compute a diff between two integers:
//!
//! ```rust
//! 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`.
//!
//! ```rust
//! use diffogus::diff::{Diffable, HashMapDiff, CollectionDiffEntry};
//! use std::collections::HashMap;
//!
//! let mut map1 = HashMap::new();
//! map1.insert("key1".to_string(), 1);
//! map1.insert("key2".to_string(), 2);
//!
//! let mut map2 = HashMap::new();
//! map2.insert("key1".to_string(), 1);
//! map2.insert("key2".to_string(), 3);
//! map2.insert("key3".to_string(), 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:
//!
//! ```toml
//! [dependencies]
//! diffogus = { version = "0.1", features = ["serde"] }
//! ```
//!
//! Example usage:
//!
//! ```no_run
//! use diffogus::diff::{Diffable, HashMapDiff};
//! use serde_json;
//! use std::collections::HashMap;
//!
//! let mut map1 = HashMap::new();
//! map1.insert("key1".to_string(), 1);
//!
//! let mut map2 = HashMap::new();
//! map2.insert("key1".to_string(), 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:
//!
//! ```toml
//! [dependencies]
//! diffogus = { version = "0.1", features = ["derive"] }
//! ```
//!
//! Example usage:
//!
//! ```no_run
//! 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.
//! ```
//!
/// Custom trait to allow for conditional serde support
/// Custom trait to allow for conditional serde support
/// Core diffing implementation
/// Diffing implementation for `serde_json::Value`
extern crate diffogus_derive;
pub use Diff;
use ;