pub struct Diff { /* private fields */ }Expand description
A line-level edit script between two blocks of text.
The script is minimal unless the changed region is very large (more than about 2,000 by 2,000 lines once common leading and trailing lines are removed). Such a region is shown as deleted and then inserted in full, so memory stays bounded.
Construct one with Diff::lines. Iterate the individual changes with
changes, ask whether the two inputs matched with
is_empty, or format the whole thing as a unified diff
through its Display implementation.
§Examples
use test_lang::{Change, Diff};
let diff = Diff::lines("a\nb\nc", "a\nB\nc");
assert!(!diff.is_empty());
// The unchanged `a` and `c` frame the one changed line.
let rendered = diff.to_string();
assert!(rendered.contains("-b"));
assert!(rendered.contains("+B"));
assert!(rendered.contains(" a"));Implementations§
Source§impl Diff
impl Diff
Sourcepub fn lines(expected: &str, actual: &str) -> Self
pub fn lines(expected: &str, actual: &str) -> Self
Compute the line-level diff between expected and actual.
Both inputs are split on \n into lines (the caller is expected to have
already normalized line endings — Snapshot does
this for you). Common leading and trailing lines are matched directly;
only the differing middle region is run through the LCS engine.
§Examples
Two identical strings produce an empty diff:
use test_lang::Diff;
let diff = Diff::lines("same\ntext", "same\ntext");
assert!(diff.is_empty());An added line shows up as an insertion:
use test_lang::{Change, Diff};
let diff = Diff::lines("one\ntwo", "one\ntwo\nthree");
let inserted: Vec<_> = diff
.changes()
.filter(|(c, _)| *c == Change::Insert)
.map(|(_, line)| line)
.collect();
assert_eq!(inserted, ["three"]);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true when the two inputs were line-for-line identical, i.e. the
diff contains no insertions or deletions.
§Examples
use test_lang::Diff;
assert!(Diff::lines("x", "x").is_empty());
assert!(!Diff::lines("x", "y").is_empty());Sourcepub fn changes(&self) -> impl Iterator<Item = (Change, &str)>
pub fn changes(&self) -> impl Iterator<Item = (Change, &str)>
Iterate over every line in the diff, in order, as (change, text) pairs.
Equal lines are included so the caller can reconstruct the full aligned
view; filter on the Change if only edits are of interest.
§Examples
use test_lang::{Change, Diff};
let diff = Diff::lines("keep\ndrop", "keep");
let deleted = diff
.changes()
.filter(|(c, _)| *c == Change::Delete)
.count();
assert_eq!(deleted, 1);