rich_ext/diff/mod.rs
1//! Diffs: an engine, terminal views and the inputs they read.
2//!
3//! - [`engine`]: Myers' O(ND) diff in linear space over any hashable
4//! elements ([`diff_lines`], [`diff_slices`]), word and character diffs for
5//! intra-line emphasis ([`diff_words`], [`diff_chars`]), [`Hunk`] grouping
6//! and [`TextDiff`], whose [`unified`](TextDiff::unified) output matches
7//! `diff -u` minus timestamps.
8//! - [`DiffView`]: a renderable diff, unified or side by side, of plain text,
9//! ANSI text ([`DiffView::ansi`], which also reports style-only changes) or,
10//! with the `testing` feature, render snapshots.
11//! - [`SourceDiff`]: a syntax-highlighted source diff with optional line links.
12//! - [`git`]: a `git diff` parser and [`PatchView`](git::PatchView), a
13//! review-style renderer with a file tree, annotations and links.
14//! - `test_report` (feature `test-report`): JUnit XML and libtest JSON test
15//! results and the `TestReport` renderable.
16//! - `assert_rich_eq!` and friends (feature `testing`): assertions that
17//! panic with a rendered diff.
18//!
19//! With colour off every change stays visible: `-`, `+` and `~` (style only)
20//! markers lead each changed line.
21
22pub mod engine;
23pub mod git;
24mod render;
25mod source;
26pub mod transform;
27mod view;
28
29#[cfg(feature = "testing")]
30pub mod assert;
31#[cfg(feature = "test-report")]
32pub mod test_report;
33
34pub use engine::{
35 diff_chars, diff_lines, diff_slices, diff_words, group_hunks, hunk_header, tokenize, Hunk, Op,
36 TextDiff,
37};
38pub use source::SourceDiff;
39pub use view::{DiffView, Side};
40
41use rich::{Console, Style};
42
43/// The default styles for diff and test-report keys. [`extended_theme`]
44/// includes them; renderers fall back to them when a theme lacks a key.
45///
46/// [`extended_theme`]: crate::theme::extended_theme
47pub const STYLES: &[(&str, &str)] = &[
48 ("diff.added", "green"),
49 ("diff.removed", "red"),
50 ("diff.added.emphasis", "bold underline green"),
51 ("diff.removed.emphasis", "bold underline red"),
52 ("diff.hunk", "cyan"),
53 ("diff.header", "bold"),
54 ("diff.line_number", "dim"),
55 ("diff.context", "none"),
56 ("test.passed", "green"),
57 ("test.failed", "bold red"),
58 ("test.errored", "bold magenta"),
59 ("test.skipped", "yellow"),
60];
61
62/// The console theme's style for `key`, else its default from [`STYLES`].
63pub(crate) fn style(console: &Console, key: &str) -> Style {
64 let fallback = STYLES
65 .iter()
66 .find(|(name, _)| *name == key)
67 .map_or("none", |(_, spec)| spec);
68 crate::event::theme_style(console, key, fallback)
69}
70
71/// How a diff is laid out.
72#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
73pub enum Layout {
74 /// One column, removed lines before added ones (the default).
75 #[default]
76 Unified,
77 /// Old on the left, new on the right, each half the width.
78 SideBySide,
79}