diffogus/lib.rs
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
#![deny(missing_docs)]
//! # 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", 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:
//!
//! ```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", 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:
//!
//! ```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.
//! ```
//!
#![cfg_attr(docsrs, feature(doc_cfg, rustdoc_internals))]
/// Core diffing implementation
pub mod diff;
#[cfg(feature = "diffogus_derive")]
extern crate diffogus_derive;
#[cfg(feature = "diffogus_derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use diffogus_derive::Diff;