1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Symbols used for diff rendering.
/// Symbols for diff rendering.
///
/// These are the prefixes shown before lines/elements to indicate
/// what kind of change occurred.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DiffSymbols {
/// Symbol for deleted content (default: "-")
pub deleted: &'static str,
/// Symbol for inserted content (default: "+")
pub inserted: &'static str,
/// Symbol for content moved from this position (default: "←")
pub moved_from: &'static str,
/// Symbol for content moved to this position (default: "→")
pub moved_to: &'static str,
}
impl Default for DiffSymbols {
fn default() -> Self {
Self::STANDARD
}
}
impl DiffSymbols {
/// Standard diff symbols using `-`, `+`, `←`, `→`
pub const STANDARD: Self = Self {
deleted: "-",
inserted: "+",
moved_from: "\u{2190}", // ←
moved_to: "\u{2192}", // →
};
/// ASCII-only symbols (for terminals that don't support Unicode)
pub const ASCII: Self = Self {
deleted: "-",
inserted: "+",
moved_from: "<-",
moved_to: "->",
};
}
/// The kind of change for a diff element.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChangeKind {
/// Content is unchanged
Unchanged,
/// Content was deleted (exists in old, not in new)
Deleted,
/// Content was inserted (exists in new, not in old)
Inserted,
/// Content was moved from this position to elsewhere
MovedFrom,
/// Content was moved to this position from elsewhere
MovedTo,
/// Content was modified (value changed)
Modified,
}
impl ChangeKind {
/// Get the symbol for this change kind.
pub const fn symbol(self, symbols: &DiffSymbols) -> Option<&'static str> {
match self {
Self::Unchanged => None,
Self::Deleted | Self::Modified => Some(symbols.deleted),
Self::Inserted => Some(symbols.inserted),
Self::MovedFrom => Some(symbols.moved_from),
Self::MovedTo => Some(symbols.moved_to),
}
}
/// Returns true if this change should be highlighted (not unchanged).
pub const fn is_changed(self) -> bool {
!matches!(self, Self::Unchanged)
}
}