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