Skip to main content

Diff

Struct Diff 

Source
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

Source

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"]);
Source

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());
Source

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);

Trait Implementations§

Source§

impl Clone for Diff

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Diff

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Diff

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Render the diff in unified style: one line per change, each prefixed with its marker and a space.

Source§

impl Eq for Diff

Source§

impl PartialEq for Diff

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Diff

Auto Trait Implementations§

§

impl Forget for Diff

§

impl Freeze for Diff

§

impl Move for Diff

§

impl RefUnwindSafe for Diff

§

impl Send for Diff

§

impl Sync for Diff

§

impl Unpin for Diff

§

impl UnsafeUnpin for Diff

§

impl UnwindSafe for Diff

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.