1use facet_reflect::Peek;
6
7use crate::Diff;
8
9pub struct Interspersed<A, B> {
12 pub first: Option<A>,
14 pub values: Vec<(B, A)>,
16 pub last: Option<B>,
18}
19
20impl<A, B> Interspersed<A, B> {
21 pub fn front_a(&mut self) -> &mut A
23 where
24 A: Default,
25 {
26 self.first.get_or_insert_default()
27 }
28
29 pub fn front_b(&mut self) -> &mut B
31 where
32 B: Default,
33 {
34 if let Some(a) = self.first.take() {
35 self.values.insert(0, (B::default(), a));
36 }
37
38 if let Some((b, _)) = self.values.first_mut() {
39 b
40 } else {
41 self.last.get_or_insert_default()
42 }
43 }
44}
45
46impl<A, B> Default for Interspersed<A, B> {
47 fn default() -> Self {
48 Self {
49 first: Default::default(),
50 values: Default::default(),
51 last: Default::default(),
52 }
53 }
54}
55
56#[derive(Default)]
58pub struct ReplaceGroup<'mem, 'facet> {
59 pub removals: Vec<Peek<'mem, 'facet>>,
61 pub additions: Vec<Peek<'mem, 'facet>>,
63}
64
65impl<'mem, 'facet> ReplaceGroup<'mem, 'facet> {
66 pub fn push_add(&mut self, addition: Peek<'mem, 'facet>) {
68 self.additions.insert(0, addition);
71 }
72
73 pub fn push_remove(&mut self, removal: Peek<'mem, 'facet>) {
75 self.removals.insert(0, removal);
76 }
77}
78
79#[derive(Default)]
81pub struct UpdatesGroup<'mem, 'facet>(
82 pub Interspersed<ReplaceGroup<'mem, 'facet>, Vec<Diff<'mem, 'facet>>>,
84);
85
86impl<'mem, 'facet> UpdatesGroup<'mem, 'facet> {
87 pub fn push_add(&mut self, addition: Peek<'mem, 'facet>) {
89 self.0.front_a().push_add(addition);
90 }
91
92 pub fn push_remove(&mut self, removal: Peek<'mem, 'facet>) {
94 self.0.front_a().push_remove(removal);
95 }
96
97 pub fn flatten_with<C, D>(&mut self, closeness_fn: C, diff_fn: D)
102 where
103 C: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> usize,
104 D: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> Diff<'mem, 'facet>,
105 {
106 let Some(updates) = self.0.first.take() else {
107 return;
108 };
109
110 let mut mem = vec![vec![0; updates.additions.len() + 1]];
113
114 for x in 0..updates.removals.len() {
115 let mut row = vec![0];
116
117 for (y, addition) in updates.additions.iter().enumerate() {
118 row.push(
119 row.last()
120 .copied()
121 .unwrap()
122 .max(mem[x][y] + closeness_fn(updates.removals[x], *addition)),
123 );
124 }
125
126 mem.push(row);
127 }
128
129 let mut x = updates.removals.len();
130 let mut y = updates.additions.len();
131
132 while x > 0 || y > 0 {
133 if x == 0 {
134 self.push_add(updates.additions[y - 1]);
135 y -= 1;
136 } else if y == 0 {
137 self.push_remove(updates.removals[x - 1]);
138 x -= 1;
139 } else if mem[x][y - 1] == mem[x][y] {
140 self.push_add(updates.additions[y - 1]);
141 y -= 1;
142 } else {
143 let diff = diff_fn(updates.removals[x - 1], updates.additions[y - 1]);
144 self.0.front_b().insert(0, diff);
145
146 x -= 1;
147 y -= 1;
148 }
149 }
150 }
151}
152
153#[derive(Default)]
155pub struct Updates<'mem, 'facet>(
156 pub Interspersed<UpdatesGroup<'mem, 'facet>, Vec<Peek<'mem, 'facet>>>,
158);
159
160impl<'mem, 'facet> Updates<'mem, 'facet> {
161 pub fn push_add(&mut self, addition: Peek<'mem, 'facet>) {
166 self.0.front_a().push_add(addition);
167 }
168
169 pub fn push_remove(&mut self, removal: Peek<'mem, 'facet>) {
174 self.0.front_a().push_remove(removal);
175 }
176
177 pub fn closeness(&self) -> usize {
179 self.0.values.iter().map(|(x, _)| x.len()).sum::<usize>()
180 + self.0.last.as_ref().map(|x| x.len()).unwrap_or_default()
181 }
182
183 pub fn push_keep(&mut self, value: Peek<'mem, 'facet>) {
188 self.0.front_b().insert(0, value);
189 }
190
191 pub fn flatten_with<C, D>(&mut self, closeness_fn: C, diff_fn: D)
193 where
194 C: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> usize + Copy,
195 D: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> Diff<'mem, 'facet> + Copy,
196 {
197 if let Some(update) = &mut self.0.first {
198 update.flatten_with(closeness_fn, diff_fn);
199 }
200
201 for (_, update) in &mut self.0.values {
202 update.flatten_with(closeness_fn, diff_fn);
203 }
204 }
205}