What is cool-diff?
cool-diff compares two serde_json::Value trees and produces a minimal, human-readable diff. It is format-agnostic at the core (operates on parsed JSON values) and ships with a YAML-style renderer out of the box.
Designed for comparing Kubernetes resources, API responses, config files, or any structured data where you want to see exactly what changed without wading through noise.
Features
- Format-agnostic diff on
serde_json::Valuetrees - Array matching by index, distinguished key, or content (contains)
- Configurable per-path array matching and ambiguity strategies
- Custom renderer support via
DiffRenderertrait - YAML-style renderer with unified diff output (
-/+indicators)- Truncation for large subtrees (
# N more lines) - Omitted field/item markers (
# N fields omitted) - ANSI colour output for terminal rendering (behind
colorfeature gate)
- Truncation for large subtrees (
- JSON renderer
- Pre-configured
MatchConfigfor common Kubernetes resource types - Inline comparison directives in the expected value
Example output
spec:
# 2 fields omitted
containers:
- name: app
# 2 items omitted
env:
- name: LOG_LEVEL
- value: debug
+ value: info
- image: "myapp:2.0"
+ image: "myapp:1.0"
Installation
Add to your Cargo.toml:
[]
= "0.1"
Quick start
use ;
let actual = json!;
let expected = json!;
let tree = diff;
if !tree.is_empty
Output:
server:
# 2 fields omitted
- port: 3000
+ port: 8080
Array matching modes
By default, arrays are compared by position (index). You can configure per-path matching via MatchConfig:
| Mode | Description |
|---|---|
| Index (default) | Match by position. Element 0 compares to element 0, etc. |
| Key | Match by a configured distinguished field (e.g. name). Scans the actual array for an element with the same key value. |
| Contains | Find a matching element anywhere. Uses exact comparison for scalars, subset matching for objects. |
use ;
let config = new.with_match_config;
Renderer
The built-in YamlRenderer produces diff output using unified diff conventions:
Every line starts with an indicator in column 0:
(space) for context lines-for expected values (what you wanted)+for actual values (what you got)
The renderer is configurable:
use YamlRenderer;
let renderer = new
.with_max_lines_per_side // truncate large subtrees
.with_indent_width; // custom indentation
You can also implement the DiffRenderer trait for custom output formats. See examples/custom_renderer.rs.
Examples
Runnable examples are in the examples/ directory:
- barebones - simplest usage with all defaults
- match_configs - mix of index, key, and contains matching
- contains_check - checking that elements exist regardless of order
- kubernetes - diffing a Kubernetes Pod with key-based array matching
- custom_renderer - implementing a custom
DiffRenderer
Run any example with:
[!TIP] Add
--features colorfor coloured output:
Changelog
See CHANGELOG.md for a list of changes per release.
Contributing
Contributions are welcome! A contributing guide is coming soon.
[!IMPORTANT] Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you shall be dual licensed under MIT and Apache-2.0, without any additional terms or conditions.
Releasing
See RELEASE.md for the release process and commit conventions.
License
Licensed under either of
at your option.