10 stable releases (3 major)

3.1.0 Mar 6, 2022
3.0.2 Feb 19, 2022
3.0.0 Oct 30, 2021
2.0.0 Oct 29, 2021
0.1.0 Oct 21, 2021

#152 in Text processing

Download history 24/week @ 2022-01-27 74/week @ 2022-02-03 6/week @ 2022-02-10 67/week @ 2022-02-17 66/week @ 2022-02-24 130/week @ 2022-03-03 57/week @ 2022-03-10 82/week @ 2022-03-17 2/week @ 2022-03-24 31/week @ 2022-03-31 45/week @ 2022-04-07 18/week @ 2022-04-14 22/week @ 2022-04-21 113/week @ 2022-04-28 121/week @ 2022-05-05 372/week @ 2022-05-12

635 downloads per month

CC0 license

68KB
367 lines

termdiff

Diff a string for presentation to a user in the terminal.

Usage

use termdiff::{SignsTheme, DrawDiff};
let old = "The quick brown fox and\njumps over the sleepy dog";
let new = "The quick red fox and\njumps over the lazy dog";
let theme = SignsTheme::default();
let actual = format!("{}", DrawDiff::new(old, new, &theme));

assert_eq!(
    actual,
    "--- remove | insert +++
-The quick brown fox and
-jumps over the sleepy dog
+The quick red fox and
+jumps over the lazy dog
"
);

Alternatively you can use this interface

use termdiff::{ArrowsTheme, diff};
let old = "The quick brown fox and\njumps over the sleepy dog";
let new = "The quick red fox and\njumps over the lazy dog";
let theme = ArrowsTheme::default();
let mut buffer: Vec<u8> = Vec::new();
diff(&mut buffer, old, new, &theme).unwrap();
let actual: String = String::from_utf8(buffer).expect("Not valid UTF-8");

assert_eq!(
    actual,
    "< left / > right
<The quick brown fox and
<jumps over the sleepy dog
>The quick red fox and
>jumps over the lazy dog
"
);

Read more at Docs.rs

Themes

We have a limited number of built in themes

Arrows

Demo of the arrows format

Signs

Demo of the signs format

Custom

use termdiff::DrawDiff;
use termdiff::Theme;
use crossterm::style::Stylize;
use std::borrow::Cow;

#[derive(Debug)]
struct MyTheme {}
impl Theme for MyTheme {fn highlight_insert<'this>(&self, input: &'this str) -> Cow<'this, str> {
        input.into()
    }

fn highlight_delete<'this>(&self, input: &'this str) -> Cow<'this, str> {
       input.into()
    }

fn equal_content<'this>(&self, input: &'this str) -> Cow<'this, str> {
       input.into()
    }

fn delete_content<'this>(&self, input: &'this str) -> Cow<'this, str> {
       input.into()
    }

fn equal_prefix<'this>(&self) -> Cow<'this, str> {
     "=".into()
    }

fn delete_prefix<'this>(&self) -> Cow<'this, str> {
        "!".into()
    }

fn insert_line<'this>(&self, input: &'this str) -> Cow<'this, str> {
     input.into()
    }

fn insert_prefix<'this>(&self) -> Cow<'this, str> {
     "|".into()
    }

fn line_end<'this>(&self) -> Cow<'this, str> {
        "\n".into()
    }

fn header<'this>(&self) -> Cow<'this, str> {
        format!("{}\n", "Header").into()
    }}
let my_theme = MyTheme{};

let old = "The quick brown fox and\njumps over the sleepy dog";
let new = "The quick red fox and\njumps over the lazy dog";
let actual = format!("{}", DrawDiff::new(old, new, &my_theme));

assert_eq!(
    actual,
    "Header
!The quick brown fox and
!jumps over the sleepy dog
|The quick red fox and
|jumps over the lazy dog
"
);

Dependencies

~1–6MB
~101K SLoC