tldr_cli/commands/remaining/difftastic/
changes.rs1use super::{
4 hash::DftHashMap,
5 syntax::{Syntax, SyntaxId},
6};
7
8#[derive(PartialEq, Eq, Clone, Copy)]
9pub enum ChangeKind<'a> {
10 Unchanged(&'a Syntax<'a>),
14 ReplacedComment(&'a Syntax<'a>, &'a Syntax<'a>),
15 ReplacedString(&'a Syntax<'a>, &'a Syntax<'a>),
16 Novel,
17}
18
19#[derive(Debug, Default)]
20pub struct ChangeMap<'a> {
21 changes: DftHashMap<SyntaxId, ChangeKind<'a>>,
22}
23
24impl<'a> ChangeMap<'a> {
25 pub fn insert(&mut self, node: &'a Syntax<'a>, ck: ChangeKind<'a>) {
26 self.changes.insert(node.id(), ck);
27 }
28
29 pub fn get(&self, node: &Syntax<'a>) -> Option<ChangeKind<'a>> {
30 self.changes.get(&node.id()).copied()
31 }
32}
33
34pub fn insert_deep_unchanged<'a>(
35 node: &'a Syntax<'a>,
36 opposite_node: &'a Syntax<'a>,
37 change_map: &mut ChangeMap<'a>,
38) {
39 change_map.insert(node, ChangeKind::Unchanged(opposite_node));
40
41 match (node, opposite_node) {
42 (
43 Syntax::List {
44 children: node_children,
45 ..
46 },
47 Syntax::List {
48 children: opposite_children,
49 ..
50 },
51 ) => {
52 for (child, opposite_child) in node_children.iter().zip(opposite_children) {
53 insert_deep_unchanged(child, opposite_child, change_map);
54 }
55 }
56 (Syntax::Atom { .. }, Syntax::Atom { .. }) => {}
57 _ => unreachable!("Unchanged nodes should be both lists, or both atoms"),
58 }
59}
60
61pub fn insert_deep_novel<'a>(node: &'a Syntax<'a>, change_map: &mut ChangeMap<'a>) {
62 change_map.insert(node, ChangeKind::Novel);
63
64 if let Syntax::List { children, .. } = node {
65 for child in children.iter() {
66 insert_deep_novel(child, change_map);
67 }
68 }
69}