Compare commits
No commits in common. "11f9b4d80b0f2f2999b3919192389ea53dfa80de" and "fdecdbc6c9bc6ce7ead8d3a96af6c2dbbd50fcb5" have entirely different histories.
11f9b4d80b
...
fdecdbc6c9
8 changed files with 37 additions and 97 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "likewise"
|
name = "likewise"
|
||||||
version = "3.1.0"
|
version = "3.0.0"
|
||||||
authors = [
|
authors = [
|
||||||
"Barrett Ruth <br.barrettruth@gmail.com>",
|
"Barrett Ruth <br.barrettruth@gmail.com>",
|
||||||
"Armin Ronacher <armin.ronacher@active-4.com>",
|
"Armin Ronacher <armin.ronacher@active-4.com>",
|
||||||
|
|
@ -11,7 +11,7 @@ edition = "2018"
|
||||||
rust-version = "1.66"
|
rust-version = "1.66"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
description = "A diff library for Rust (fork of similar)"
|
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"]
|
keywords = ["diff", "difference", "patience", "compare", "changes"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
exclude = ["assets/*"]
|
exclude = ["assets/*"]
|
||||||
|
|
|
||||||
11
README.md
11
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.
|
> This crate is a fork of [similar](https://github.com/mitsuhiko/similar) library, which, as of 11/9/25, is rather inactive.
|
||||||
|
|
||||||
[](https://crates.io/crates/likewise)
|
[](https://crates.io/crates/likewise)
|
||||||
[](https://github.com/barrettruth/likewise/blob/main/LICENSE)
|
[](https://github.com/frozen/likewise/blob/main/LICENSE)
|
||||||
[](https://img.shields.io/badge/rust-1.65%2B-orange.svg)
|
[](https://img.shields.io/badge/rust-1.65%2B-orange.svg)
|
||||||
[](https://docs.rs/likewise)
|
[](https://docs.rs/likewise)
|
||||||
|
|
||||||
|
|
@ -44,20 +44,19 @@ fn main() {
|
||||||
* Patience diff
|
* Patience diff
|
||||||
* Hunt–McIlroy / Hunt–Szymanski LCS diff
|
* Hunt–McIlroy / Hunt–Szymanski LCS diff
|
||||||
* Diffing on arbitrary comparable sequences
|
* Diffing on arbitrary comparable sequences
|
||||||
* **Floating point comparison with epsilon tolerance**
|
|
||||||
* Line, word, character and grapheme level diffing
|
* Line, word, character and grapheme level diffing
|
||||||
* Text and Byte diffing
|
* Text and Byte diffing
|
||||||
* Unified diff generation
|
* Unified diff generation
|
||||||
|
|
||||||
## Related Projects
|
## Related Projects
|
||||||
|
|
||||||
* [similar](https://github.com/mitsuhiko/similar) the original library
|
* [similar](https://github.com/mitsuhiko/similar)
|
||||||
* [insta](https://insta.rs) snapshot testing library
|
* [insta](https://insta.rs) snapshot testing library
|
||||||
* [similar-asserts](https://github.com/mitsuhiko/similar-asserts) assertion library
|
* [similar-asserts](https://github.com/mitsuhiko/similar-asserts) assertion library
|
||||||
|
|
||||||
## License and Links
|
## License and Links
|
||||||
|
|
||||||
* [Documentation](https://docs.rs/likewise/)
|
* [Documentation](https://docs.rs/likewise/)
|
||||||
* [Issue Tracker](https://github.com/barrettruth/likewise/issues)
|
* [Issue Tracker](https://github.com/barrett-ruth/likewise/issues)
|
||||||
* [Examples](https://github.com/barrettruth/likewise/tree/main/examples)
|
* [Examples](https://github.com/barrett-ruth/likewise/tree/main/examples)
|
||||||
* License: [Apache-2.0](https://github.com/barrettruth/likewise/blob/main/LICENSE)
|
* License: [Apache-2.0](https://github.com/barrett-ruth/likewise/blob/main/LICENSE)
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ fn main() {
|
||||||
// Strict comparison would show many differences due to measurement noise
|
// Strict comparison would show many differences due to measurement noise
|
||||||
// FP comparison with 0.05 tolerance treats small variations as equal
|
// FP comparison with 0.05 tolerance treats small variations as equal
|
||||||
let ops = capture_diff_slices_fp(
|
let ops = capture_diff_slices_fp(
|
||||||
Algorithm::Myers,
|
Algorithm::Myers,
|
||||||
&baseline_readings,
|
&baseline_readings,
|
||||||
¤t_readings,
|
¤t_readings,
|
||||||
0.05,
|
0.05
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("Baseline: {:?}", baseline_readings);
|
println!("Baseline: {:?}", baseline_readings);
|
||||||
|
|
@ -20,9 +20,7 @@ fn main() {
|
||||||
println!("With epsilon=0.05: {} diff operations", ops.len());
|
println!("With epsilon=0.05: {} diff operations", ops.len());
|
||||||
|
|
||||||
for op in &ops {
|
for op in &ops {
|
||||||
let changes: Vec<_> = op
|
let changes: Vec<_> = op.iter_changes(&baseline_readings, ¤t_readings).collect();
|
||||||
.iter_changes(&baseline_readings, ¤t_readings)
|
|
||||||
.collect();
|
|
||||||
for change in changes {
|
for change in changes {
|
||||||
match change.tag() {
|
match change.tag() {
|
||||||
ChangeTag::Equal => println!(" ✓ Equal: {}", change.value()),
|
ChangeTag::Equal => println!(" ✓ Equal: {}", change.value()),
|
||||||
|
|
@ -43,16 +41,8 @@ fn main() {
|
||||||
for &epsilon in &[0.0001, 0.001, 0.01] {
|
for &epsilon in &[0.0001, 0.001, 0.01] {
|
||||||
let ops = capture_diff_slices_fp(Algorithm::Myers, &old, &new, epsilon);
|
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, .. });
|
let all_equal = ops.len() == 1 && matches!(ops[0], likewise::DiffOp::Equal { len: 3, .. });
|
||||||
println!(
|
println!(" epsilon={}: {} ({})", epsilon, ops.len(),
|
||||||
" epsilon={}: {} ({})",
|
if all_equal { "all equal" } else { "differences found" });
|
||||||
epsilon,
|
|
||||||
ops.len(),
|
|
||||||
if all_equal {
|
|
||||||
"all equal"
|
|
||||||
} else {
|
|
||||||
"differences found"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example 3: Edge cases with NaN and infinity
|
// 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 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);
|
let ops_f64 = capture_diff_slices_fp_f64(Algorithm::Myers, &old_f64, &new_f64, 1e-12);
|
||||||
println!(
|
println!("f64 comparison with epsilon=1e-12: {} operations", ops_f64.len());
|
||||||
"f64 comparison with epsilon=1e-12: {} operations",
|
}
|
||||||
ops_f64.len()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -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>(
|
pub fn diff_fp_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f32],
|
old: &[f32],
|
||||||
|
|
@ -312,10 +308,6 @@ where
|
||||||
crate::algorithms::myers::diff_fp_deadline(d, old, old_range, new, new_range, epsilon, deadline)
|
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>(
|
pub fn diff_fp_f64_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f64],
|
old: &[f64],
|
||||||
|
|
@ -328,7 +320,5 @@ pub fn diff_fp_f64_deadline<D>(
|
||||||
where
|
where
|
||||||
D: DiffHook,
|
D: DiffHook,
|
||||||
{
|
{
|
||||||
crate::algorithms::myers::diff_fp_f64_deadline(
|
crate::algorithms::myers::diff_fp_f64_deadline(d, old, old_range, new, new_range, epsilon, deadline)
|
||||||
d, old, old_range, new, new_range, epsilon, deadline,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,3 +132,4 @@ where
|
||||||
{
|
{
|
||||||
diff_deadline(alg, d, old, 0..old.len(), new, 0..new.len(), deadline)
|
diff_deadline(alg, d, old, 0..old.len(), new, 0..new.len(), deadline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,7 @@
|
||||||
|
|
||||||
use std::ops::{Index, IndexMut, Range};
|
use std::ops::{Index, IndexMut, Range};
|
||||||
|
|
||||||
use crate::algorithms::utils::{
|
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};
|
||||||
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::DiffHook;
|
use crate::algorithms::DiffHook;
|
||||||
use crate::deadline_support::{deadline_exceeded, Instant};
|
use crate::deadline_support::{deadline_exceeded, Instant};
|
||||||
|
|
||||||
|
|
@ -445,9 +442,6 @@ fn test_finish_called() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Myers' diff algorithm with f32 epsilon comparison.
|
/// 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>(
|
pub fn diff_fp_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f32],
|
old: &[f32],
|
||||||
|
|
@ -463,16 +457,11 @@ where
|
||||||
let max_d = max_d(old_range.len(), new_range.len());
|
let max_d = max_d(old_range.len(), new_range.len());
|
||||||
let mut vb = V::new(max_d);
|
let mut vb = V::new(max_d);
|
||||||
let mut vf = V::new(max_d);
|
let mut vf = V::new(max_d);
|
||||||
conquer_fp(
|
conquer_fp(d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline)?;
|
||||||
d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline,
|
|
||||||
)?;
|
|
||||||
d.finish()
|
d.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Myers' diff algorithm with f64 epsilon comparison.
|
/// 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>(
|
pub fn diff_fp_f64_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f64],
|
old: &[f64],
|
||||||
|
|
@ -488,9 +477,7 @@ where
|
||||||
let max_d = max_d(old_range.len(), new_range.len());
|
let max_d = max_d(old_range.len(), new_range.len());
|
||||||
let mut vb = V::new(max_d);
|
let mut vb = V::new(max_d);
|
||||||
let mut vf = V::new(max_d);
|
let mut vf = V::new(max_d);
|
||||||
conquer_fp_f64(
|
conquer_fp_f64(d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline)?;
|
||||||
d, old, old_range, new, new_range, epsilon, &mut vf, &mut vb, deadline,
|
|
||||||
)?;
|
|
||||||
d.finish()
|
d.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,8 +681,7 @@ where
|
||||||
D: DiffHook,
|
D: DiffHook,
|
||||||
{
|
{
|
||||||
// Check for common prefix
|
// Check for common prefix
|
||||||
let common_prefix_len =
|
let common_prefix_len = common_prefix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon);
|
||||||
common_prefix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon);
|
|
||||||
if common_prefix_len > 0 {
|
if common_prefix_len > 0 {
|
||||||
d.equal(old_range.start, new_range.start, common_prefix_len)?;
|
d.equal(old_range.start, new_range.start, common_prefix_len)?;
|
||||||
}
|
}
|
||||||
|
|
@ -703,8 +689,7 @@ where
|
||||||
new_range.start += common_prefix_len;
|
new_range.start += common_prefix_len;
|
||||||
|
|
||||||
// Check for common suffix
|
// Check for common suffix
|
||||||
let common_suffix_len =
|
let common_suffix_len = common_suffix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon);
|
||||||
common_suffix_len_fp(old, old_range.clone(), new, new_range.clone(), epsilon);
|
|
||||||
let common_suffix = (
|
let common_suffix = (
|
||||||
old_range.end - common_suffix_len,
|
old_range.end - common_suffix_len,
|
||||||
new_range.end - common_suffix_len,
|
new_range.end - common_suffix_len,
|
||||||
|
|
@ -768,8 +753,7 @@ where
|
||||||
D: DiffHook,
|
D: DiffHook,
|
||||||
{
|
{
|
||||||
// Check for common prefix
|
// Check for common prefix
|
||||||
let common_prefix_len =
|
let common_prefix_len = common_prefix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon);
|
||||||
common_prefix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon);
|
|
||||||
if common_prefix_len > 0 {
|
if common_prefix_len > 0 {
|
||||||
d.equal(old_range.start, new_range.start, common_prefix_len)?;
|
d.equal(old_range.start, new_range.start, common_prefix_len)?;
|
||||||
}
|
}
|
||||||
|
|
@ -777,8 +761,7 @@ where
|
||||||
new_range.start += common_prefix_len;
|
new_range.start += common_prefix_len;
|
||||||
|
|
||||||
// Check for common suffix
|
// Check for common suffix
|
||||||
let common_suffix_len =
|
let common_suffix_len = common_suffix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon);
|
||||||
common_suffix_len_fp_f64(old, old_range.clone(), new, new_range.clone(), epsilon);
|
|
||||||
let common_suffix = (
|
let common_suffix = (
|
||||||
old_range.end - common_suffix_len,
|
old_range.end - common_suffix_len,
|
||||||
new_range.end - common_suffix_len,
|
new_range.end - common_suffix_len,
|
||||||
|
|
|
||||||
|
|
@ -197,10 +197,6 @@ fn test_finish_called() {
|
||||||
assert!(d.0);
|
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>(
|
pub fn diff_fp_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f32],
|
old: &[f32],
|
||||||
|
|
@ -216,10 +212,6 @@ where
|
||||||
crate::algorithms::myers::diff_fp_deadline(d, old, old_range, new, new_range, epsilon, deadline)
|
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>(
|
pub fn diff_fp_f64_deadline<D>(
|
||||||
d: &mut D,
|
d: &mut D,
|
||||||
old: &[f64],
|
old: &[f64],
|
||||||
|
|
@ -232,7 +224,5 @@ pub fn diff_fp_f64_deadline<D>(
|
||||||
where
|
where
|
||||||
D: DiffHook,
|
D: DiffHook,
|
||||||
{
|
{
|
||||||
crate::algorithms::myers::diff_fp_f64_deadline(
|
crate::algorithms::myers::diff_fp_f64_deadline(d, old, old_range, new, new_range, epsilon, deadline)
|
||||||
d, old, old_range, new, new_range, epsilon, deadline,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,15 +124,9 @@ fn capture_diff_fp_deadline(
|
||||||
) -> Vec<DiffOp> {
|
) -> Vec<DiffOp> {
|
||||||
let mut d = Compact::new(Replace::new(Capture::new()), old, new);
|
let mut d = Compact::new(Replace::new(Capture::new()), old, new);
|
||||||
let result = match alg {
|
let result = match alg {
|
||||||
Algorithm::Myers => crate::algorithms::myers::diff_fp_deadline(
|
Algorithm::Myers => crate::algorithms::myers::diff_fp_deadline(&mut d, old, old_range, new, new_range, epsilon, 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::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();
|
result.unwrap();
|
||||||
d.into_inner().into_inner().into_ops()
|
d.into_inner().into_inner().into_ops()
|
||||||
|
|
@ -149,15 +143,9 @@ fn capture_diff_fp_f64_deadline(
|
||||||
) -> Vec<DiffOp> {
|
) -> Vec<DiffOp> {
|
||||||
let mut d = Compact::new(Replace::new(Capture::new()), old, new);
|
let mut d = Compact::new(Replace::new(Capture::new()), old, new);
|
||||||
let result = match alg {
|
let result = match alg {
|
||||||
Algorithm::Myers => crate::algorithms::myers::diff_fp_f64_deadline(
|
Algorithm::Myers => crate::algorithms::myers::diff_fp_f64_deadline(&mut d, old, old_range, new, new_range, epsilon, 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::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();
|
result.unwrap();
|
||||||
d.into_inner().into_inner().into_ops()
|
d.into_inner().into_inner().into_ops()
|
||||||
|
|
@ -280,10 +268,10 @@ fn test_non_string_iter_change() {
|
||||||
fn test_fp_epsilon() {
|
fn test_fp_epsilon() {
|
||||||
let old = vec![1.0, 2.0, 3.0];
|
let old = vec![1.0, 2.0, 3.0];
|
||||||
let new = vec![1.001, 2.0, 2.999];
|
let new = vec![1.001, 2.0, 2.999];
|
||||||
|
|
||||||
let ops_tight = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.0001);
|
let ops_tight = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.0001);
|
||||||
assert!(ops_tight.len() > 1);
|
assert!(ops_tight.len() > 1);
|
||||||
|
|
||||||
let ops_loose = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.01);
|
let ops_loose = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.01);
|
||||||
assert_eq!(ops_loose.len(), 1);
|
assert_eq!(ops_loose.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +280,9 @@ fn test_fp_epsilon() {
|
||||||
fn test_fp_nan() {
|
fn test_fp_nan() {
|
||||||
let old = vec![f32::NAN];
|
let old = vec![f32::NAN];
|
||||||
let new = vec![f32::NAN];
|
let new = vec![f32::NAN];
|
||||||
|
|
||||||
let ops = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.001);
|
let ops = capture_diff_slices_fp(Algorithm::Myers, &old, &new, 0.001);
|
||||||
assert_eq!(ops.len(), 1);
|
assert_eq!(ops.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue