1use std::borrow::Borrow;
19use std::collections::HashMap;
20use std::fmt::Debug;
21use std::fmt::Formatter;
22use std::fmt::Write as _;
23use std::future::Future;
24use std::hash::Hash;
25use std::iter::zip;
26use std::slice;
27use std::sync::Arc;
28
29use futures::future::try_join_all;
30use itertools::Itertools as _;
31use smallvec::SmallVec;
32use smallvec::smallvec_inline;
33
34use crate::backend::BackendResult;
35use crate::backend::CopyId;
36use crate::backend::FileId;
37use crate::backend::TreeValue;
38use crate::content_hash::ContentHash;
39use crate::content_hash::DigestUpdate;
40use crate::repo_path::RepoPath;
41use crate::store::Store;
42use crate::tree::Tree;
43
44#[derive(Clone, Debug, PartialEq, Eq)]
49pub struct Diff<T> {
50 pub before: T,
52 pub after: T,
54}
55
56impl<T> Diff<T> {
57 pub fn new(before: T, after: T) -> Self {
59 Self { before, after }
60 }
61
62 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Diff<U> {
64 Diff {
65 before: f(self.before),
66 after: f(self.after),
67 }
68 }
69}
70
71impl<T: Eq> Diff<T> {
72 pub fn is_changed(&self) -> bool {
75 self.before != self.after
76 }
77}
78
79#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize)]
81#[serde(rename_all = "kebab-case")]
82pub enum SameChange {
83 Keep,
85 Accept,
92}
93
94pub fn trivial_merge<T>(values: &[T], same_change: SameChange) -> Option<&T>
97where
98 T: Eq + Hash,
99{
100 assert!(
101 values.len() % 2 == 1,
102 "trivial_merge() requires an odd number of terms"
103 );
104 if let [add] = values {
106 return Some(add);
107 } else if let [add0, remove, add1] = values {
108 return if add0 == add1 && same_change == SameChange::Accept {
109 Some(add0)
110 } else if add0 == remove {
111 Some(add1)
112 } else if add1 == remove {
113 Some(add0)
114 } else {
115 None
116 };
117 }
118
119 let mut counts: HashMap<&T, i32> = HashMap::new();
123 for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
124 counts.entry(value).and_modify(|e| *e += n).or_insert(n);
125 }
126
127 counts.retain(|_, count| *count != 0);
130 if counts.len() == 1 {
131 let (value, count) = counts.into_iter().next().unwrap();
133 assert_eq!(count, 1);
134 Some(value)
135 } else if counts.len() == 2 && same_change == SameChange::Accept {
136 let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
138 assert_eq!(count1 + count2, 1);
139 if count1 > 0 {
140 Some(value1)
141 } else {
142 Some(value2)
143 }
144 } else {
145 None
146 }
147}
148
149#[derive(PartialEq, Eq, Hash, Clone, serde::Serialize)]
155#[serde(transparent)]
156pub struct Merge<T> {
157 values: SmallVec<[T; 1]>,
159}
160
161impl<T: Debug> Debug for Merge<T> {
162 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
163 if let Some(value) = self.as_resolved() {
166 f.debug_tuple("Resolved").field(value).finish()
167 } else {
168 f.debug_tuple("Conflicted").field(&self.values).finish()
169 }
170 }
171}
172
173impl<T> Merge<T> {
174 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
177 let values = values.into();
178 assert!(values.len() % 2 != 0, "must have an odd number of terms");
179 Self { values }
180 }
181
182 pub fn from_removes_adds(
184 removes: impl IntoIterator<Item = T>,
185 adds: impl IntoIterator<Item = T>,
186 ) -> Self {
187 let removes = removes.into_iter();
188 let mut adds = adds.into_iter();
189 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
190 values.push(adds.next().expect("must have at least one add"));
191 for diff in removes.zip_longest(adds) {
192 let (remove, add) = diff.both().expect("must have one more adds than removes");
193 values.extend([remove, add]);
194 }
195 Self { values }
196 }
197
198 pub const fn resolved(value: T) -> Self {
200 Self {
201 values: smallvec_inline![value],
202 }
203 }
204
205 pub fn from_legacy_form(
208 removes: impl IntoIterator<Item = T>,
209 adds: impl IntoIterator<Item = T>,
210 ) -> Merge<Option<T>> {
211 let removes = removes.into_iter();
212 let mut adds = adds.into_iter().fuse();
213 let mut values = smallvec_inline![adds.next()];
214 for diff in removes.zip_longest(adds) {
215 let (remove, add) = diff.map_any(Some, Some).or_default();
216 values.extend([remove, add]);
217 }
218 Merge { values }
219 }
220
221 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
223 self.values[1..].iter().step_by(2)
224 }
225
226 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
228 self.values.iter().step_by(2)
229 }
230
231 pub fn first(&self) -> &T {
233 &self.values[0]
234 }
235
236 pub fn get_remove(&self, index: usize) -> Option<&T> {
239 self.values.get(index * 2 + 1)
240 }
241
242 pub fn get_add(&self, index: usize) -> Option<&T> {
246 self.values.get(index * 2)
247 }
248
249 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
252 let add = self.values.swap_remove(add_index * 2);
254 let remove = self.values.swap_remove(remove_index * 2 + 1);
255 (remove, add)
256 }
257
258 pub fn num_sides(&self) -> usize {
260 self.values.len() / 2 + 1
261 }
262
263 pub fn is_resolved(&self) -> bool {
265 self.values.len() == 1
266 }
267
268 pub fn as_resolved(&self) -> Option<&T> {
271 if let [value] = &self.values[..] {
272 Some(value)
273 } else {
274 None
275 }
276 }
277
278 pub fn into_resolved(mut self) -> Result<T, Self> {
281 if self.values.len() == 1 {
282 Ok(self.values.pop().unwrap())
283 } else {
284 Err(self)
285 }
286 }
287
288 fn get_simplified_mapping(&self) -> Vec<usize>
294 where
295 T: PartialEq,
296 {
297 let unsimplified_len = self.values.len();
298 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
299
300 let mut add_index = 0;
301 while add_index < simplified_to_original_indices.len() {
302 let add = &self.values[simplified_to_original_indices[add_index]];
303 let mut remove_indices = simplified_to_original_indices
304 .iter()
305 .enumerate()
306 .skip(1)
307 .step_by(2);
308 if let Some((remove_index, _)) = remove_indices
309 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
310 {
311 simplified_to_original_indices.swap(remove_index + 1, add_index);
314 simplified_to_original_indices.drain(remove_index..remove_index + 2);
315 } else {
316 add_index += 2;
317 }
318 }
319
320 simplified_to_original_indices
321 }
322
323 #[must_use]
326 pub fn simplify(&self) -> Self
327 where
328 T: PartialEq + Clone,
329 {
330 let mapping = self.get_simplified_mapping();
331 let values = mapping
333 .iter()
334 .map(|index| self.values[*index].clone())
335 .collect();
336 Self { values }
337 }
338
339 pub fn update_from_simplified(mut self, simplified: Self) -> Self
341 where
342 T: PartialEq,
343 {
344 let mapping = self.get_simplified_mapping();
345 assert_eq!(mapping.len(), simplified.values.len());
346 for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
347 self.values[index] = value;
348 }
349 self
350 }
351
352 pub fn resolve_trivial(&self, same_change: SameChange) -> Option<&T>
355 where
356 T: Eq + Hash,
357 {
358 trivial_merge(&self.values, same_change)
359 }
360
361 pub fn pad_to(&mut self, num_sides: usize, value: &T)
364 where
365 T: Clone,
366 {
367 if num_sides <= self.num_sides() {
368 return;
369 }
370 self.values.resize(num_sides * 2 - 1, value.clone());
371 }
372
373 pub fn as_slice(&self) -> &[T] {
377 &self.values
378 }
379
380 pub fn iter(&self) -> slice::Iter<'_, T> {
384 self.values.iter()
385 }
386
387 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
389 self.values.iter_mut()
390 }
391
392 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
394 let values = self.values.iter().map(f).collect();
395 Merge { values }
396 }
397
398 pub fn try_map<'a, U, E>(
401 &'a self,
402 f: impl FnMut(&'a T) -> Result<U, E>,
403 ) -> Result<Merge<U>, E> {
404 let values = self.values.iter().map(f).try_collect()?;
405 Ok(Merge { values })
406 }
407
408 pub async fn try_map_async<'a, F, U, E>(
412 &'a self,
413 f: impl FnMut(&'a T) -> F,
414 ) -> Result<Merge<U>, E>
415 where
416 F: Future<Output = Result<U, E>>,
417 {
418 let values = try_join_all(self.values.iter().map(f)).await?;
419 Ok(Merge {
420 values: values.into(),
421 })
422 }
423}
424
425#[derive(Clone, Debug, PartialEq, Eq)]
434pub struct MergeBuilder<T> {
435 values: SmallVec<[T; 1]>,
436}
437
438impl<T> Default for MergeBuilder<T> {
439 fn default() -> Self {
440 Self {
441 values: Default::default(),
442 }
443 }
444}
445
446impl<T> MergeBuilder<T> {
447 pub fn build(self) -> Merge<T> {
450 Merge::from_vec(self.values)
451 }
452}
453
454impl<T> IntoIterator for Merge<T> {
455 type Item = T;
456 type IntoIter = smallvec::IntoIter<[T; 1]>;
457
458 fn into_iter(self) -> Self::IntoIter {
459 self.values.into_iter()
460 }
461}
462
463impl<T> FromIterator<T> for MergeBuilder<T> {
464 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
465 let mut builder = Self::default();
466 builder.extend(iter);
467 builder
468 }
469}
470
471impl<T> Extend<T> for MergeBuilder<T> {
472 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
473 self.values.extend(iter);
474 }
475}
476
477impl<T> Merge<Option<T>> {
478 pub fn absent() -> Self {
480 Self::resolved(None)
481 }
482
483 pub fn normal(value: T) -> Self {
485 Self::resolved(Some(value))
486 }
487
488 pub fn is_absent(&self) -> bool {
490 matches!(self.as_resolved(), Some(None))
491 }
492
493 pub fn is_present(&self) -> bool {
495 !self.is_absent()
496 }
497
498 pub fn as_normal(&self) -> Option<&T> {
500 self.as_resolved()?.as_ref()
501 }
502
503 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
507 let mut removes = Vec::with_capacity(self.values.len() / 2);
509 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
510 let mut values = self.values.into_iter();
511 adds.extend(values.next().unwrap());
512 while let Some(remove) = values.next() {
513 removes.extend(remove);
514 adds.extend(values.next().unwrap());
515 }
516 (removes, adds)
517 }
518}
519
520impl<T: Clone> Merge<Option<&T>> {
521 pub fn cloned(&self) -> Merge<Option<T>> {
523 self.map(|value| value.cloned())
524 }
525}
526
527impl<T> Merge<Merge<T>> {
528 pub fn flatten(self) -> Merge<T> {
546 let mut outer_values = self.values.into_iter();
547 let mut result = outer_values.next().unwrap();
548 while let Some(mut remove) = outer_values.next() {
549 remove.values.rotate_left(1);
552 for i in 0..remove.values.len() / 2 {
553 remove.values.swap(i * 2, i * 2 + 1);
554 }
555 result.values.extend(remove.values);
556 let add = outer_values.next().unwrap();
557 result.values.extend(add.values);
558 }
559 result
560 }
561}
562
563impl<T: ContentHash> ContentHash for Merge<T> {
564 fn hash(&self, state: &mut impl DigestUpdate) {
565 self.values.hash(state);
566 }
567}
568
569pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
571
572pub type MergedTreeValue = Merge<Option<TreeValue>>;
579
580impl<T> Merge<Option<T>>
581where
582 T: Borrow<TreeValue>,
583{
584 pub fn is_tree(&self) -> bool {
586 self.is_present()
587 && self.iter().all(|value| {
588 matches!(
589 borrow_tree_value(value.as_ref()),
590 Some(TreeValue::Tree(_)) | None
591 )
592 })
593 }
594
595 pub fn is_file_like(&self) -> bool {
597 self.is_present() && !self.is_tree()
598 }
599
600 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
605 let file_ids = self
606 .try_map(|term| match borrow_tree_value(term.as_ref()) {
607 None => Ok(None),
608 Some(TreeValue::File {
609 id,
610 executable: _,
611 copy_id: _,
612 }) => Ok(Some(id.clone())),
613 _ => Err(()),
614 })
615 .ok()?;
616
617 Some(file_ids)
618 }
619
620 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
623 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
624 None => Ok(None),
625 Some(TreeValue::File {
626 id: _,
627 executable,
628 copy_id: _,
629 }) => Ok(Some(*executable)),
630 _ => Err(()),
631 })
632 .ok()
633 }
634
635 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
638 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
639 None => Ok(None),
640 Some(TreeValue::File {
641 id: _,
642 executable: _,
643 copy_id,
644 }) => Ok(Some(copy_id.clone())),
645 _ => Err(()),
646 })
647 .ok()
648 }
649
650 pub async fn to_tree_merge(
655 &self,
656 store: &Arc<Store>,
657 dir: &RepoPath,
658 ) -> BackendResult<Option<Merge<Tree>>> {
659 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
660 None => Ok(None),
661 Some(TreeValue::Tree(id)) => Ok(Some(id)),
662 Some(_) => Err(()),
663 });
664 if let Ok(tree_id_merge) = tree_id_merge {
665 Ok(Some(
666 tree_id_merge
667 .try_map_async(async |id| {
668 if let Some(id) = id {
669 store.get_tree_async(dir.to_owned(), id).await
670 } else {
671 Ok(Tree::empty(store.clone(), dir.to_owned()))
672 }
673 })
674 .await?,
675 ))
676 } else {
677 Ok(None)
678 }
679 }
680
681 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
687 assert_eq!(self.values.len(), file_ids.values.len());
688 let values = zip(self.iter(), file_ids.iter().cloned())
689 .map(
690 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
691 (
692 Some(TreeValue::File {
693 id: _,
694 executable,
695 copy_id,
696 }),
697 Some(id),
698 ) => Some(TreeValue::File {
699 id,
700 executable: *executable,
701 copy_id: copy_id.clone(),
702 }),
703 (None, None) => None,
704 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
705 },
706 )
707 .collect();
708 Merge { values }
709 }
710
711 pub fn describe(&self) -> String {
713 let mut buf = String::new();
714 writeln!(buf, "Conflict:").unwrap();
715 for term in self.removes().flatten() {
716 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
717 }
718 for term in self.adds().flatten() {
719 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
720 }
721 buf
722 }
723}
724
725fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
726 term.map(|value| value.borrow())
727}
728
729fn describe_conflict_term(value: &TreeValue) -> String {
730 match value {
731 TreeValue::File {
732 id,
733 executable: false,
734 copy_id: _,
735 } => {
736 format!("file with id {id}")
738 }
739 TreeValue::File {
740 id,
741 executable: true,
742 copy_id: _,
743 } => {
744 format!("executable file with id {id}")
746 }
747 TreeValue::Symlink(id) => {
748 format!("symlink with id {id}")
749 }
750 TreeValue::Tree(id) => {
751 format!("tree with id {id}")
752 }
753 TreeValue::GitSubmodule(id) => {
754 format!("Git submodule with id {id}")
755 }
756 }
757}
758
759#[cfg(test)]
760mod tests {
761 use test_case::test_case;
762
763 use super::*;
764
765 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
766 Merge::from_vec(terms.to_vec())
767 }
768
769 #[test_case(SameChange::Keep)]
770 #[test_case(SameChange::Accept)]
771 fn test_trivial_merge(same_change: SameChange) {
772 let accept_same_change = same_change == SameChange::Accept;
773 let merge = |values| trivial_merge(values, same_change);
774 assert_eq!(merge(&[0]), Some(&0));
775 assert_eq!(merge(&[0, 0, 0]), Some(&0));
776 assert_eq!(merge(&[0, 0, 1]), Some(&1));
777 assert_eq!(merge(&[0, 1, 0]), accept_same_change.then_some(&0));
778 assert_eq!(merge(&[0, 1, 1]), Some(&0));
779 assert_eq!(merge(&[0, 1, 2]), None);
780 assert_eq!(merge(&[0, 0, 0, 0, 0]), Some(&0));
781 assert_eq!(merge(&[0, 0, 0, 0, 1]), Some(&1));
782 assert_eq!(merge(&[0, 0, 0, 1, 0]), accept_same_change.then_some(&0));
783 assert_eq!(merge(&[0, 0, 0, 1, 1]), Some(&0));
784 assert_eq!(merge(&[0, 0, 0, 1, 2]), None);
785 assert_eq!(merge(&[0, 0, 1, 0, 0]), Some(&1));
786 assert_eq!(merge(&[0, 0, 1, 0, 1]), accept_same_change.then_some(&1));
787 assert_eq!(merge(&[0, 0, 1, 0, 2]), None);
788 assert_eq!(merge(&[0, 0, 1, 1, 0]), Some(&0));
789 assert_eq!(merge(&[0, 0, 1, 1, 1]), Some(&1));
790 assert_eq!(merge(&[0, 0, 1, 1, 2]), Some(&2));
791 assert_eq!(merge(&[0, 0, 1, 2, 0]), None);
792 assert_eq!(merge(&[0, 0, 1, 2, 1]), accept_same_change.then_some(&1));
793 assert_eq!(merge(&[0, 0, 1, 2, 2]), Some(&1));
794 assert_eq!(merge(&[0, 0, 1, 2, 3]), None);
795 assert_eq!(merge(&[0, 1, 0, 0, 0]), accept_same_change.then_some(&0));
796 assert_eq!(merge(&[0, 1, 0, 0, 1]), Some(&0));
797 assert_eq!(merge(&[0, 1, 0, 0, 2]), None);
798 assert_eq!(merge(&[0, 1, 0, 1, 0]), accept_same_change.then_some(&0));
799 assert_eq!(merge(&[0, 1, 0, 1, 1]), accept_same_change.then_some(&0));
800 assert_eq!(merge(&[0, 1, 0, 1, 2]), None);
801 assert_eq!(merge(&[0, 1, 0, 2, 0]), None);
802 assert_eq!(merge(&[0, 1, 0, 2, 1]), accept_same_change.then_some(&0));
803 assert_eq!(merge(&[0, 1, 0, 2, 2]), accept_same_change.then_some(&0));
804 assert_eq!(merge(&[0, 1, 0, 2, 3]), None);
805 assert_eq!(merge(&[0, 1, 1, 0, 0]), Some(&0));
806 assert_eq!(merge(&[0, 1, 1, 0, 1]), Some(&1));
807 assert_eq!(merge(&[0, 1, 1, 0, 2]), Some(&2));
808 assert_eq!(merge(&[0, 1, 1, 1, 0]), accept_same_change.then_some(&0));
809 assert_eq!(merge(&[0, 1, 1, 1, 1]), Some(&0));
810 assert_eq!(merge(&[0, 1, 1, 1, 2]), None);
811 assert_eq!(merge(&[0, 1, 1, 2, 0]), accept_same_change.then_some(&0));
812 assert_eq!(merge(&[0, 1, 1, 2, 1]), None);
813 assert_eq!(merge(&[0, 1, 1, 2, 2]), Some(&0));
814 assert_eq!(merge(&[0, 1, 1, 2, 3]), None);
815 assert_eq!(merge(&[0, 1, 2, 0, 0]), None);
816 assert_eq!(merge(&[0, 1, 2, 0, 1]), Some(&2));
817 assert_eq!(merge(&[0, 1, 2, 0, 2]), accept_same_change.then_some(&2));
818 assert_eq!(merge(&[0, 1, 2, 0, 3]), None);
819 assert_eq!(merge(&[0, 1, 2, 1, 0]), None);
820 assert_eq!(merge(&[0, 1, 2, 1, 1]), None);
821 assert_eq!(merge(&[0, 1, 2, 1, 2]), None);
822 assert_eq!(merge(&[0, 1, 2, 1, 3]), None);
823 assert_eq!(merge(&[0, 1, 2, 2, 0]), accept_same_change.then_some(&0));
824 assert_eq!(merge(&[0, 1, 2, 2, 1]), Some(&0));
825 assert_eq!(merge(&[0, 1, 2, 2, 2]), None);
826 assert_eq!(merge(&[0, 1, 2, 2, 3]), None);
827 assert_eq!(merge(&[0, 1, 2, 3, 0]), None);
828 assert_eq!(merge(&[0, 1, 2, 3, 1]), None);
829 assert_eq!(merge(&[0, 1, 2, 3, 2]), None);
830 assert_eq!(merge(&[0, 1, 2, 3, 3]), None);
831 assert_eq!(merge(&[0, 1, 2, 3, 4]), None);
832 }
833
834 #[test]
835 fn test_legacy_form_conversion() {
836 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
837 where
838 T: Clone + PartialEq + std::fmt::Debug,
839 {
840 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
841 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
842 }
843 test_equivalent(
845 (vec![], vec![0]),
846 Merge::from_removes_adds(vec![], vec![Some(0)]),
847 );
848 test_equivalent(
850 (vec![0], vec![1, 2]),
851 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
852 );
853 test_equivalent(
855 (vec![0], vec![1]),
856 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
857 );
858 test_equivalent(
860 (vec![], vec![0, 1]),
861 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
862 );
863 test_equivalent(
865 (vec![0, 1], vec![2, 3, 4]),
866 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
867 );
868 test_equivalent(
870 (vec![0, 1], vec![]),
871 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
872 );
873 }
874
875 #[test]
876 fn test_as_resolved() {
877 assert_eq!(
878 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
879 Some(&0)
880 );
881 assert_eq!(
883 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
884 None
885 );
886 }
887
888 #[test]
889 fn test_get_simplified_mapping() {
890 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
892 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
894 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
895 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
896 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
897 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
898 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
900 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
901 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
902 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
903 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
904 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
905 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
906 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
907 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
908 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
909 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
910 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
911 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
912 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
913 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
914 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
915 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
916 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
917 assert_eq!(
918 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
919 vec![0, 1, 2, 3, 4]
920 );
921 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
922 assert_eq!(
923 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
924 vec![0, 1, 2, 3, 4]
925 );
926 assert_eq!(
927 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
928 vec![0, 1, 2, 3, 4]
929 );
930 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
931 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
932 assert_eq!(
933 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
934 vec![0, 1, 2, 3, 4]
935 );
936 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
937 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
938 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
939 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
940 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
941 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
942 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
943 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
944 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
945 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
946 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
947 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
948 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
949 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
950 assert_eq!(
951 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
952 vec![0, 1, 2, 3, 4]
953 );
954 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
955 assert_eq!(
956 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
957 vec![0, 1, 2, 3, 4]
958 );
959 assert_eq!(
960 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
961 vec![0, 1, 2, 3, 4]
962 );
963 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
964 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
965 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
966 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
967 assert_eq!(
968 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
969 vec![0, 1, 2, 3, 4]
970 );
971 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
972 assert_eq!(
973 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
974 vec![0, 1, 2, 3, 4]
975 );
976 assert_eq!(
977 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
978 vec![0, 3, 4, 5, 2]
979 );
980 assert_eq!(
981 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
982 vec![0, 1, 2, 3, 4]
983 );
984 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
985 }
986
987 #[test]
988 fn test_simplify() {
989 assert_eq!(c(&[0]).simplify(), c(&[0]));
991 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
993 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
994 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
995 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
996 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
997 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
999 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
1000 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
1001 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
1002 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
1003 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
1004 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
1005 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
1006 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
1007 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
1008 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
1009 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
1010 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
1011 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
1012 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
1013 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
1014 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
1015 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
1016 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
1017 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
1018 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1019 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1020 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1021 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1022 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1023 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1024 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1025 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1026 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1027 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1028 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1029 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1030 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1031 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1032 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1033 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1034 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1035 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1036 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1037 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1038 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1039 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1040 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1041 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1042 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1043 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1044 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1045 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1046 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1047 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1048 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1049 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1050 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1051 }
1052
1053 #[test]
1054 fn test_update_from_simplified() {
1055 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1057 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1059 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1060 assert_eq!(
1061 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1062 c(&[2, 1, 3])
1063 );
1064 assert_eq!(
1066 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1067 c(&[0, 0, 0, 0, 1])
1068 );
1069 assert_eq!(
1070 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1071 c(&[0, 0, 2, 3, 1])
1072 );
1073 assert_eq!(
1074 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1075 c(&[0, 3, 1, 0, 2])
1076 );
1077 assert_eq!(
1078 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1079 c(&[3, 1, 4, 2, 5])
1080 );
1081
1082 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1083 assert_eq!(
1086 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1087 c(&[0, 0, 10, 1, 11, 2, 4])
1088 );
1089 }
1090
1091 #[test]
1092 fn test_merge_invariants() {
1093 fn check_invariants(terms: &[u32]) {
1094 let merge = Merge::from_vec(terms.to_vec());
1095 assert_eq!(
1097 merge.simplify().simplify(),
1098 merge.simplify(),
1099 "simplify() not idempotent for {merge:?}"
1100 );
1101 assert_eq!(
1103 merge.simplify().resolve_trivial(SameChange::Accept),
1104 merge.resolve_trivial(SameChange::Accept),
1105 "simplify() changed result of resolve_trivial() for {merge:?}"
1106 );
1107 }
1108 check_invariants(&[0]);
1110 for i in 0..=1 {
1111 for j in 0..=i + 1 {
1112 check_invariants(&[i, 0, j]);
1114 for k in 0..=j + 1 {
1115 for l in 0..=k + 1 {
1116 check_invariants(&[0, i, j, k, l]);
1118 }
1119 }
1120 }
1121 }
1122 }
1123
1124 #[test]
1125 fn test_swap_remove() {
1126 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1127 assert_eq!(x.swap_remove(0, 1), (1, 2));
1128 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1129 assert_eq!(x.swap_remove(1, 0), (3, 0));
1130 assert_eq!(x, c(&[4, 5, 6]));
1131 assert_eq!(x.swap_remove(0, 1), (5, 6));
1132 assert_eq!(x, c(&[4]));
1133 }
1134
1135 #[test]
1136 fn test_pad_to() {
1137 let mut x = c(&[1]);
1138 x.pad_to(3, &2);
1139 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1140 x.pad_to(1, &3);
1142 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1143 }
1144
1145 #[test]
1146 fn test_iter() {
1147 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1149 assert_eq!(
1151 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1152 vec![&1, &2, &3, &4, &5]
1153 );
1154 }
1155
1156 #[test]
1157 fn test_from_iter() {
1158 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1160 assert_eq!(
1162 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1163 c(&[1, 2, 3, 4, 5])
1164 );
1165 }
1166
1167 #[test]
1168 #[should_panic]
1169 fn test_from_iter_empty() {
1170 MergeBuilder::from_iter([1; 0]).build();
1171 }
1172
1173 #[test]
1174 #[should_panic]
1175 fn test_from_iter_even() {
1176 MergeBuilder::from_iter([1, 2]).build();
1177 }
1178
1179 #[test]
1180 fn test_extend() {
1181 let mut builder: MergeBuilder<i32> = Default::default();
1183 builder.extend([1]);
1184 assert_eq!(builder.build(), c(&[1]));
1185 let mut builder: MergeBuilder<i32> = Default::default();
1187 builder.extend([1, 2]);
1188 builder.extend([3, 4, 5]);
1189 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1190 }
1191
1192 #[test]
1193 fn test_map() {
1194 fn increment(i: &i32) -> i32 {
1195 i + 1
1196 }
1197 assert_eq!(c(&[1]).map(increment), c(&[2]));
1199 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1201 }
1202
1203 #[test]
1204 fn test_try_map() {
1205 fn sqrt(i: &i32) -> Result<i32, ()> {
1206 if *i >= 0 {
1207 Ok((*i as f64).sqrt() as i32)
1208 } else {
1209 Err(())
1210 }
1211 }
1212 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1214 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1215 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1217 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1218 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1219 }
1220
1221 #[test]
1222 fn test_flatten() {
1223 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1225 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1227 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1229 assert_eq!(
1231 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1232 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1233 );
1234 }
1235}