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.removals.len() + 1]];
111
112 for x in 0..updates.removals.len() {
113 let mut row = vec![0];
114
115 for (y, addition) in updates.additions.iter().enumerate() {
116 row.push(
117 row.last()
118 .copied()
119 .unwrap()
120 .max(mem[x][y] + closeness_fn(updates.removals[x], *addition)),
121 );
122 }
123
124 mem.push(row);
125 }
126
127 let mut x = updates.removals.len();
128 let mut y = updates.additions.len();
129
130 while x > 0 || y > 0 {
131 if x == 0 {
132 self.push_add(updates.additions[y - 1]);
133 y -= 1;
134 } else if y == 0 {
135 self.push_remove(updates.removals[x - 1]);
136 x -= 1;
137 } else if mem[x][y - 1] == mem[x][y] {
138 self.push_add(updates.additions[y - 1]);
139 y -= 1;
140 } else {
141 let diff = diff_fn(updates.removals[x - 1], updates.additions[y - 1]);
142 self.0.front_b().insert(0, diff);
143
144 x -= 1;
145 y -= 1;
146 }
147 }
148 }
149}
150
151#[derive(Default)]
153pub struct Updates<'mem, 'facet>(
154 pub Interspersed<UpdatesGroup<'mem, 'facet>, Vec<Peek<'mem, 'facet>>>,
156);
157
158impl<'mem, 'facet> Updates<'mem, 'facet> {
159 pub fn push_add(&mut self, addition: Peek<'mem, 'facet>) {
164 self.0.front_a().push_add(addition);
165 }
166
167 pub fn push_remove(&mut self, removal: Peek<'mem, 'facet>) {
172 self.0.front_a().push_remove(removal);
173 }
174
175 pub fn closeness(&self) -> usize {
177 self.0.values.iter().map(|(x, _)| x.len()).sum::<usize>()
178 + self.0.last.as_ref().map(|x| x.len()).unwrap_or_default()
179 }
180
181 pub fn push_keep(&mut self, value: Peek<'mem, 'facet>) {
186 self.0.front_b().insert(0, value);
187 }
188
189 pub fn flatten_with<C, D>(&mut self, closeness_fn: C, diff_fn: D)
191 where
192 C: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> usize + Copy,
193 D: Fn(Peek<'mem, 'facet>, Peek<'mem, 'facet>) -> Diff<'mem, 'facet> + Copy,
194 {
195 if let Some(update) = &mut self.0.first {
196 update.flatten_with(closeness_fn, diff_fn);
197 }
198
199 for (_, update) in &mut self.0.values {
200 update.flatten_with(closeness_fn, diff_fn);
201 }
202 }
203}