diff --git a/Cargo.toml b/Cargo.toml index 6f514c5..b4b9238 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "likewise" -version = "3.1.0" +version = "3.0.0" authors = [ "Barrett Ruth ", "Armin Ronacher ", @@ -11,7 +11,7 @@ edition = "2018" rust-version = "1.66" license = "Apache-2.0" description = "A diff library for Rust (fork of similar)" -repository = "https://github.com/barrettruth/likewise" +repository = "https://github.com/barrett-ruth/likewise" keywords = ["diff", "difference", "patience", "compare", "changes"] readme = "README.md" exclude = ["assets/*"] diff --git a/README.md b/README.md index 574aac6..df09b35 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ > This crate is a fork of [similar](https://github.com/mitsuhiko/similar) library, which, as of 11/9/25, is rather inactive. [![Crates.io](https://img.shields.io/crates/d/likewise.svg)](https://crates.io/crates/likewise) -[![License](https://img.shields.io/github/license/barrettruth/likewise)](https://github.com/barrettruth/likewise/blob/main/LICENSE) +[![License](https://img.shields.io/github/license/frozen/likewise)](https://github.com/frozen/likewise/blob/main/LICENSE) [![rustc 1.66.0](https://img.shields.io/badge/rust-1.66%2B-orange.svg)](https://img.shields.io/badge/rust-1.65%2B-orange.svg) [![Documentation](https://docs.rs/likewise/badge.svg)](https://docs.rs/likewise) @@ -44,20 +44,19 @@ fn main() { * Patience diff * Hunt–McIlroy / Hunt–Szymanski LCS diff * Diffing on arbitrary comparable sequences -* **Floating point comparison with epsilon tolerance** * Line, word, character and grapheme level diffing * Text and Byte diffing * Unified diff generation ## Related Projects -* [similar](https://github.com/mitsuhiko/similar) the original library +* [similar](https://github.com/mitsuhiko/similar) * [insta](https://insta.rs) snapshot testing library * [similar-asserts](https://github.com/mitsuhiko/similar-asserts) assertion library ## License and Links * [Documentation](https://docs.rs/likewise/) -* [Issue Tracker](https://github.com/barrettruth/likewise/issues) -* [Examples](https://github.com/barrettruth/likewise/tree/main/examples) -* License: [Apache-2.0](https://github.com/barrettruth/likewise/blob/main/LICENSE) +* [Issue Tracker](https://github.com/barrett-ruth/likewise/issues) +* [Examples](https://github.com/barrett-ruth/likewise/tree/main/examples) +* License: [Apache-2.0](https://github.com/barrett-ruth/likewise/blob/main/LICENSE) diff --git a/examples/floating-point.rs b/examples/floating_point.rs similarity index 80% rename from examples/floating-point.rs rename to examples/floating_point.rs index b6bfe6a..de71f7f 100644 --- a/examples/floating-point.rs +++ b/examples/floating_point.rs @@ -9,10 +9,10 @@ fn main() { // Strict comparison would show many differences due to measurement noise // FP comparison with 0.05 tolerance treats small variations as equal let ops = capture_diff_slices_fp( - Algorithm::Myers, - &baseline_readings, - ¤t_readings, - 0.05, + Algorithm::Myers, + &baseline_readings, + ¤t_readings, + 0.05 ); println!("Baseline: {:?}", baseline_readings); @@ -20,9 +20,7 @@ fn main() { println!("With epsilon=0.05: {} diff operations", ops.len()); for op in &ops { - let changes: Vec<_> = op - .iter_changes(&baseline_readings, ¤t_readings) - .collect(); + let changes: Vec<_> = op.iter_changes(&baseline_readings, ¤t_readings).collect(); for change in changes { match change.tag() { ChangeTag::Equal => println!(" ✓ Equal: {}", change.value()), @@ -43,16 +41,8 @@ fn main() { for &epsilon in &[0.0001, 0.001, 0.01] { let ops = capture_diff_slices_fp(Algorithm::Myers, &old, &new, epsilon); let all_equal = ops.len() == 1 && matches!(ops[0], likewise::DiffOp::Equal { len: 3, .. }); - println!( - " epsilon={}: {} ({})", - epsilon, - ops.len(), - if all_equal { - "all equal" - } else { - "differences found" - } - ); + println!(" epsilon={}: {} ({})", epsilon, ops.len(), + if all_equal { "all equal" } else { "differences found" }); } // Example 3: Edge cases with NaN and infinity @@ -71,8 +61,5 @@ fn main() { let new_f64 = vec![1.0000000000002, 2.0, 3.141592653589794]; let ops_f64 = capture_diff_slices_fp_f64(Algorithm::Myers, &old_f64, &new_f64, 1e-12); - println!( - "f64 comparison with epsilon=1e-12: {} operations", - ops_f64.len() - ); -} + println!("f64 comparison with epsilon=1e-12: {} operations", ops_f64.len()); +} \ No newline at end of file diff --git a/src/algorithms/lcs.rs b/src/algorithms/lcs.rs index bbcf112..b052bad 100644 --- a/src/algorithms/lcs.rs +++ b/src/algorithms/lcs.rs @@ -293,10 +293,6 @@ fn test_bad_range_regression() { ); } -/// LCS diff algorithm with f32 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_deadline( d: &mut D, old: &[f32], @@ -312,10 +308,6 @@ where crate::algorithms::myers::diff_fp_deadline(d, old, old_range, new, new_range, epsilon, deadline) } -/// LCS diff algorithm with f64 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_f64_deadline( d: &mut D, old: &[f64], @@ -328,7 +320,5 @@ pub fn diff_fp_f64_deadline( where D: DiffHook, { - crate::algorithms::myers::diff_fp_f64_deadline( - d, old, old_range, new, new_range, epsilon, deadline, - ) + crate::algorithms::myers::diff_fp_f64_deadline(d, old, old_range, new, new_range, epsilon, deadline) } diff --git a/src/algorithms/mod.rs b/src/algorithms/mod.rs index 0a43afc..0e252e1 100644 --- a/src/algorithms/mod.rs +++ b/src/algorithms/mod.rs @@ -132,3 +132,4 @@ where { diff_deadline(alg, d, old, 0..old.len(), new, 0..new.len(), deadline) } + diff --git a/src/algorithms/myers.rs b/src/algorithms/myers.rs index 72405e4..2fda69f 100644 --- a/src/algorithms/myers.rs +++ b/src/algorithms/myers.rs @@ -21,10 +21,7 @@ use std::ops::{Index, IndexMut, Range}; -use crate::algorithms::utils::{ - common_prefix_len, common_prefix_len_fp, common_prefix_len_fp_f64, common_suffix_len, - common_suffix_len_fp, common_suffix_len_fp_f64, is_empty_range, -}; +use crate::algorithms::utils::{common_prefix_len, common_suffix_len, common_prefix_len_fp, common_suffix_len_fp, common_prefix_len_fp_f64, common_suffix_len_fp_f64, is_empty_range}; use crate::algorithms::DiffHook; use crate::deadline_support::{deadline_exceeded, Instant}; @@ -445,9 +442,6 @@ fn test_finish_called() { } /// Myers' diff algorithm with f32 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_deadline( d: &mut D, old: &[f32], @@ -463,16 +457,11 @@ where let max_d = max_d(old_range.len(), new_range.len()); let mut vb = V::new(max_d); let mut vf = V::new(max_d); - conquer_fp( - d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline, - )?; + conquer_fp(d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline)?; d.finish() } /// Myers' diff algorithm with f64 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_f64_deadline( d: &mut D, old: &[f64], @@ -488,9 +477,7 @@ where let max_d = max_d(old_range.len(), new_range.len()); let mut vb = V::new(max_d); let mut vf = V::new(max_d); - conquer_fp_f64( - d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline, - )?; + conquer_fp_f64(d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline)?; d.finish() } @@ -694,8 +681,7 @@ where D: DiffHook, { // Check for common prefix - let common_prefix_len = - common_prefix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon); + let common_prefix_len = common_prefix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon); if common_prefix_len > 0 { d.equal(old_range.start, new_range.start, common_prefix_len)?; } @@ -703,8 +689,7 @@ where new_range.start += common_prefix_len; // Check for common suffix - let common_suffix_len = - common_suffix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon); + let common_suffix_len = common_suffix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon); let common_suffix = ( old_range.end - common_suffix_len, new_range.end - common_suffix_len, @@ -768,8 +753,7 @@ where D: DiffHook, { // Check for common prefix - let common_prefix_len = - common_prefix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon); + let common_prefix_len = common_prefix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon); if common_prefix_len > 0 { d.equal(old_range.start, new_range.start, common_prefix_len)?; } @@ -777,8 +761,7 @@ where new_range.start += common_prefix_len; // Check for common suffix - let common_suffix_len = - common_suffix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon); + let common_suffix_len = common_suffix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon); let common_suffix = ( old_range.end - common_suffix_len, new_range.end - common_suffix_len, diff --git a/src/algorithms/patience.rs b/src/algorithms/patience.rs index ec5f1bb..c5d757e 100644 --- a/src/algorithms/patience.rs +++ b/src/algorithms/patience.rs @@ -197,10 +197,6 @@ fn test_finish_called() { assert!(d.0); } -/// Patience diff algorithm with f32 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_deadline( d: &mut D, old: &[f32], @@ -216,10 +212,6 @@ where crate::algorithms::myers::diff_fp_deadline(d, old, old_range, new, new_range, epsilon, deadline) } -/// Patience diff algorithm with f64 epsilon comparison. -/// -/// Diff `old`, between indices `old_range` and `new` between indices `new_range`. -/// Values are considered equal if their absolute difference is within `epsilon`. pub fn diff_fp_f64_deadline( d: &mut D, old: &[f64], @@ -232,7 +224,5 @@ pub fn diff_fp_f64_deadline( where D: DiffHook, { - crate::algorithms::myers::diff_fp_f64_deadline( - d, old, old_range, new, new_range, epsilon, deadline, - ) + crate::algorithms::myers::diff_fp_f64_deadline(d, old, old_range, new, new_range, epsilon, deadline) } diff --git a/src/common.rs b/src/common.rs index 3f7ff26..51f76c0 100644 --- a/src/common.rs +++ b/src/common.rs @@ -124,15 +124,9 @@ fn capture_diff_fp_deadline( ) -> Vec { let mut d = Compact::new(Replace::new(Capture::new()), old, new); let result = match alg { - Algorithm::Myers => crate::algorithms::myers::diff_fp_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), - Algorithm::Patience => crate::algorithms::patience::diff_fp_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), - Algorithm::Lcs => crate::algorithms::lcs::diff_fp_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), + Algorithm::Myers => crate::algorithms::myers::diff_fp_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), + Algorithm::Patience => crate::algorithms::patience::diff_fp_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), + Algorithm::Lcs => crate::algorithms::lcs::diff_fp_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), }; result.unwrap(); d.into_inner().into_inner().into_ops() @@ -149,15 +143,9 @@ fn capture_diff_fp_f64_deadline( ) -> Vec { let mut d = Compact::new(Replace::new(Capture::new()), old, new); let result = match alg { - Algorithm::Myers => crate::algorithms::myers::diff_fp_f64_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), - Algorithm::Patience => crate::algorithms::patience::diff_fp_f64_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), - Algorithm::Lcs => crate::algorithms::lcs::diff_fp_f64_deadline( - &mut d, old, old_range, new, new_range, epsilon, deadline, - ), + Algorithm::Myers => crate::algorithms::myers::diff_fp_f64_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), + Algorithm::Patience => crate::algorithms::patience::diff_fp_f64_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), + Algorithm::Lcs => crate::algorithms::lcs::diff_fp_f64_deadline(&mut d, old, old_range, new, new_range, epsilon, deadline), }; result.unwrap(); d.into_inner().into_inner().into_ops() @@ -280,10 +268,10 @@ fn test_non_string_iter_change() { fn test_fp_epsilon() { let old = vec![1.0, 2.0, 3.0]; let new = vec![1.001, 2.0, 2.999]; - + let ops_tight = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.0001); assert!(ops_tight.len() > 1); - + let ops_loose = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.01); assert_eq!(ops_loose.len(), 1); } @@ -292,7 +280,9 @@ fn test_fp_epsilon() { fn test_fp_nan() { let old = vec![f32::NAN]; let new = vec![f32::NAN]; - + let ops = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.001); assert_eq!(ops.len(), 1); } + +