jsondiffpatch

Crates.iojsondiffpatch
lib.rsjsondiffpatch
version0.1.0
created_at2025-06-29 09:40:00.148201+00
updated_at2025-06-29 09:40:00.148201+00
descriptionJSON diff & patch (object and array diff, text diff, multiple output formats)
homepage
repositoryhttps://github.com/soraxas/jsondiffpatch
max_upload_size
id1730593
size96,958
Tin Lai (soraxas)

documentation

README

jsondiffpatch-rs

A Rust implementation of JSON diff & patch functionality, providing object and array diff, text diff, and multiple output formats.

This is a Rust clone of the original jsondiffpatch TypeScript library.

Features

  • Object Diffing: Compare JSON objects and generate deltas
  • Array Diffing: Detect array changes including moves, inserts, and deletes
  • Text Diffing: Character-level text comparison using diff-match-patch
  • Pipeline Architecture: Modular filter-based processing pipeline
  • Delta Operations: Create, apply, and reverse deltas
  • Error Handling: Comprehensive error types for robust operation

Quick Start

use jsondiffpatch_rs::DiffPatcher;
use serde_json::json;

fn main() {
    // Create a diff patcher instance
    let diffpatcher = DiffPatcher::new(None);

    // Create two JSON objects to compare
    let left = json!({
        "name": "John",
        "age": 30,
        "city": "New York"
    });

    let right = json!({
        "name": "John",
        "age": 31,
        "city": "Boston"
    });

    // Generate a delta
    if let Some(delta) = diffpatcher.diff(&left, &right) {
        println!("Delta: {:?}", delta);

        // Apply the delta to get the right object
        if let Some(patched) = diffpatcher.patch(&left, delta) {
            println!("Patched: {}", patched);
        }
    }
}

API Reference

Core Types

DiffPatcher

Main entry point for diff and patch operations.

let diffpatcher = DiffPatcher::new(Some(options));

Delta<'a>

Represents changes between JSON values:

  • Delta::Added(&'a Value) - A new value was added
  • Delta::Modified(&'a Value, &'a Value) - A value was changed
  • Delta::Deleted(&'a Value) - A value was removed
  • Delta::Object(HashMap<String, Delta<'a>>) - Object property changes
  • Delta::Array(Vec<(ArrayDeltaIndex, Delta<'a>)>) - Array element changes
  • Delta::Moved { moved_value: Option<&'a Value>, new_index: usize } - Array element was moved
  • Delta::TextDiff(String) - Text-level changes
  • Delta::None - No changes

Options

Configuration options for the diffing process:

use jsondiffpatch_rs::types::{Options, ArrayOptions, TextDiffOptions};

let options = Options {
    match_by_position: Some(false),
    arrays: Some(ArrayOptions {
        detect_move: Some(true),
        include_value_on_move: Some(false),
    }),
    text_diff: Some(TextDiffOptions {
        min_length: Some(60),
    }),
    clone_diff_values: Some(false),
    omit_removed_values: Some(false),
};

Main Methods

diff(left: &'a Value, right: &'a Value) -> Option<Delta<'a>>

Generates a delta representing the differences between two JSON values.

patch(left: &Value, delta: Delta) -> Option<Value>

Applies a delta to a JSON value to produce the target value.

reverse(delta: &Delta) -> Option<Delta>

Reverses a delta to create an inverse delta.

unpatch(right: &Value, delta: &Delta) -> Option<Value>

Reverses a delta to get the original value from the target value.

Examples

Object Diffing

use jsondiffpatch_rs::DiffPatcher;
use serde_json::json;

let diffpatcher = DiffPatcher::new(None);
let left = json!({"a": 1, "b": 2});
let right = json!({"a": 1, "b": 3, "c": 4});

if let Some(delta) = diffpatcher.diff(&left, &right) {
    // delta will contain changes for "b" and "c"
    println!("Delta: {:?}", delta);
}

Array Diffing

let left = json!([1, 2, 3]);
let right = json!([1, 4, 2, 3]);

if let Some(delta) = diffpatcher.diff(&left, &right) {
    // delta will contain array changes including moves
    println!("Array delta: {:?}", delta);
}

Text Diffing

let left = json!("hello world");
let right = json!("hello rust world");

if let Some(delta) = diffpatcher.diff(&left, &right) {
    // delta will contain text-level changes using diff-match-patch
    println!("Text delta: {:?}", delta);
}

Applying Patches

let left = json!({"name": "John", "age": 30});
let delta = diffpatcher.diff(&left, &right).unwrap();

if let Some(patched) = diffpatcher.patch(&left, delta) {
    assert_eq!(patched, right);
}

Architecture

The library follows a pipeline-based architecture:

Core Components

  • Processor: Manages the processing pipeline and context flow
  • Pipeline: Defines the interface for processing operations (diff, patch, reverse)
  • Contexts: Carry data through the processing pipeline
    • DiffContext: Handles diff operations
    • PatchContext: Handles patch operations
    • ReverseContext: Handles reverse operations
  • Filters: Handle specific types of data processing

Pipeline Structure

// Diff pipeline
DiffPipeline -> [ObjectFilter, ArrayFilter, TextFilter, ...]

// Patch pipeline
PatchPipeline -> [ObjectFilter, ArrayFilter, TextFilter, ...]

Error Handling

The library provides comprehensive error handling through JsonDiffPatchError:

use jsondiffpatch_rs::errors::JsonDiffPatchError;

match diffpatcher.diff(&left, &right) {
    Some(delta) => println!("Success: {:?}", delta),
    None => println!("No differences found"),
}

Delta Format

The library uses a compact delta format compatible with the original jsondiffpatch:

Serialization

Deltas can be converted to JSON format for storage/transmission:

if let Some(delta) = diffpatcher.diff(&left, &right) {
    let serialized = delta.to_serializable();
    println!("Serialized delta: {}", serialized);
}

Magic Numbers

The library uses magic numbers to identify special operations:

  • 0: Deleted items
  • 2: Text diff operations
  • 3: Array move operations

Status

Current implementation status:

  • ✅ Core architecture and pipeline system
  • ✅ Basic types and error handling
  • ✅ Object diffing and patching
  • ✅ Array diffing with move detection
  • ✅ Text diffing using diff-match-patch
  • ✅ Delta serialization and deserialization
  • ✅ Comprehensive test coverage
  • 🔄 Reverse operations (planned)
  • 🔄 Performance optimizations (ongoing)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see the LICENSE file for details.

Acknowledgments

This project is based on the original jsondiffpatch library

Commit count: 0

cargo fmt