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::repo_path::RepoPathComponent;
42use crate::store::Store;
43use crate::tree::Tree;
44
45#[derive(Copy, Clone, Debug, PartialEq, Eq)]
50pub struct Diff<T> {
51 pub before: T,
53 pub after: T,
55}
56
57impl<T> Diff<T> {
58 pub fn new(before: T, after: T) -> Self {
60 Self { before, after }
61 }
62
63 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Diff<U> {
65 Diff {
66 before: f(self.before),
67 after: f(self.after),
68 }
69 }
70
71 pub fn as_ref(&self) -> Diff<&T> {
73 Diff {
74 before: &self.before,
75 after: &self.after,
76 }
77 }
78
79 pub fn into_array(self) -> [T; 2] {
81 [self.before, self.after]
82 }
83}
84
85impl<T: Eq> Diff<T> {
86 pub fn is_changed(&self) -> bool {
89 self.before != self.after
90 }
91}
92
93#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize)]
95#[serde(rename_all = "kebab-case")]
96pub enum SameChange {
97 Keep,
99 Accept,
106}
107
108pub fn trivial_merge<T>(values: &[T], same_change: SameChange) -> Option<&T>
111where
112 T: Eq + Hash,
113{
114 assert!(
115 values.len() % 2 == 1,
116 "trivial_merge() requires an odd number of terms"
117 );
118 if let [add] = values {
120 return Some(add);
121 } else if let [add0, remove, add1] = values {
122 return if add0 == add1 && same_change == SameChange::Accept {
123 Some(add0)
124 } else if add0 == remove {
125 Some(add1)
126 } else if add1 == remove {
127 Some(add0)
128 } else {
129 None
130 };
131 }
132
133 let mut counts: HashMap<&T, i32> = HashMap::new();
137 for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
138 counts.entry(value).and_modify(|e| *e += n).or_insert(n);
139 }
140
141 counts.retain(|_, count| *count != 0);
144 if counts.len() == 1 {
145 let (value, count) = counts.into_iter().next().unwrap();
147 assert_eq!(count, 1);
148 Some(value)
149 } else if counts.len() == 2 && same_change == SameChange::Accept {
150 let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
152 assert_eq!(count1 + count2, 1);
153 if count1 > 0 {
154 Some(value1)
155 } else {
156 Some(value2)
157 }
158 } else {
159 None
160 }
161}
162
163#[derive(PartialEq, Eq, Hash, Clone, serde::Serialize)]
169#[serde(transparent)]
170pub struct Merge<T> {
171 values: SmallVec<[T; 1]>,
173}
174
175impl<T: Debug> Debug for Merge<T> {
176 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
177 if let Some(value) = self.as_resolved() {
180 f.debug_tuple("Resolved").field(value).finish()
181 } else {
182 f.debug_tuple("Conflicted").field(&self.values).finish()
183 }
184 }
185}
186
187impl<T> Merge<T> {
188 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
191 let values = values.into();
192 assert!(values.len() % 2 != 0, "must have an odd number of terms");
193 Self { values }
194 }
195
196 pub fn from_removes_adds(
198 removes: impl IntoIterator<Item = T>,
199 adds: impl IntoIterator<Item = T>,
200 ) -> Self {
201 let removes = removes.into_iter();
202 let mut adds = adds.into_iter();
203 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
204 values.push(adds.next().expect("must have at least one add"));
205 for diff in removes.zip_longest(adds) {
206 let (remove, add) = diff.both().expect("must have one more adds than removes");
207 values.extend([remove, add]);
208 }
209 Self { values }
210 }
211
212 pub const fn resolved(value: T) -> Self {
214 Self {
215 values: smallvec_inline![value],
216 }
217 }
218
219 pub fn from_legacy_form(
222 removes: impl IntoIterator<Item = T>,
223 adds: impl IntoIterator<Item = T>,
224 ) -> Merge<Option<T>> {
225 let removes = removes.into_iter();
226 let mut adds = adds.into_iter().fuse();
227 let mut values = smallvec_inline![adds.next()];
228 for diff in removes.zip_longest(adds) {
229 let (remove, add) = diff.map_any(Some, Some).or_default();
230 values.extend([remove, add]);
231 }
232 Merge { values }
233 }
234
235 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
237 self.values[1..].iter().step_by(2)
238 }
239
240 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
242 self.values.iter().step_by(2)
243 }
244
245 pub fn first(&self) -> &T {
247 &self.values[0]
248 }
249
250 pub fn get_remove(&self, index: usize) -> Option<&T> {
253 self.values.get(index * 2 + 1)
254 }
255
256 pub fn get_add(&self, index: usize) -> Option<&T> {
260 self.values.get(index * 2)
261 }
262
263 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
266 let add = self.values.swap_remove(add_index * 2);
268 let remove = self.values.swap_remove(remove_index * 2 + 1);
269 (remove, add)
270 }
271
272 pub fn num_sides(&self) -> usize {
274 self.values.len() / 2 + 1
275 }
276
277 pub fn is_resolved(&self) -> bool {
279 self.values.len() == 1
280 }
281
282 pub fn as_resolved(&self) -> Option<&T> {
285 if let [value] = &self.values[..] {
286 Some(value)
287 } else {
288 None
289 }
290 }
291
292 pub fn into_resolved(mut self) -> Result<T, Self> {
295 if self.values.len() == 1 {
296 Ok(self.values.pop().unwrap())
297 } else {
298 Err(self)
299 }
300 }
301
302 fn get_simplified_mapping(&self) -> Vec<usize>
308 where
309 T: PartialEq,
310 {
311 let unsimplified_len = self.values.len();
312 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
313
314 let mut add_index = 0;
315 while add_index < simplified_to_original_indices.len() {
316 let add = &self.values[simplified_to_original_indices[add_index]];
317 let mut remove_indices = simplified_to_original_indices
318 .iter()
319 .enumerate()
320 .skip(1)
321 .step_by(2);
322 if let Some((remove_index, _)) = remove_indices
323 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
324 {
325 simplified_to_original_indices.swap(remove_index + 1, add_index);
328 simplified_to_original_indices.drain(remove_index..remove_index + 2);
329 } else {
330 add_index += 2;
331 }
332 }
333
334 simplified_to_original_indices
335 }
336
337 #[must_use]
340 pub fn simplify(&self) -> Self
341 where
342 T: PartialEq + Clone,
343 {
344 let mapping = self.get_simplified_mapping();
345 let values = mapping
347 .iter()
348 .map(|index| self.values[*index].clone())
349 .collect();
350 Self { values }
351 }
352
353 pub fn update_from_simplified(mut self, simplified: Self) -> Self
355 where
356 T: PartialEq,
357 {
358 let mapping = self.get_simplified_mapping();
359 assert_eq!(mapping.len(), simplified.values.len());
360 for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
361 self.values[index] = value;
362 }
363 self
364 }
365
366 pub fn resolve_trivial(&self, same_change: SameChange) -> Option<&T>
369 where
370 T: Eq + Hash,
371 {
372 trivial_merge(&self.values, same_change)
373 }
374
375 pub fn pad_to(&mut self, num_sides: usize, value: &T)
378 where
379 T: Clone,
380 {
381 if num_sides <= self.num_sides() {
382 return;
383 }
384 self.values.resize(num_sides * 2 - 1, value.clone());
385 }
386
387 pub fn as_slice(&self) -> &[T] {
391 &self.values
392 }
393
394 pub fn iter(&self) -> slice::Iter<'_, T> {
398 self.values.iter()
399 }
400
401 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
403 self.values.iter_mut()
404 }
405
406 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
408 let values = self.values.iter().map(f).collect();
409 Merge { values }
410 }
411
412 pub fn try_map<'a, U, E>(
415 &'a self,
416 f: impl FnMut(&'a T) -> Result<U, E>,
417 ) -> Result<Merge<U>, E> {
418 let values = self.values.iter().map(f).try_collect()?;
419 Ok(Merge { values })
420 }
421
422 pub async fn try_map_async<'a, F, U, E>(
426 &'a self,
427 f: impl FnMut(&'a T) -> F,
428 ) -> Result<Merge<U>, E>
429 where
430 F: Future<Output = Result<U, E>>,
431 {
432 let values = try_join_all(self.values.iter().map(f)).await?;
433 Ok(Merge {
434 values: values.into(),
435 })
436 }
437}
438
439#[derive(Clone, Debug, PartialEq, Eq)]
448pub struct MergeBuilder<T> {
449 values: SmallVec<[T; 1]>,
450}
451
452impl<T> Default for MergeBuilder<T> {
453 fn default() -> Self {
454 Self {
455 values: Default::default(),
456 }
457 }
458}
459
460impl<T> MergeBuilder<T> {
461 pub fn build(self) -> Merge<T> {
464 Merge::from_vec(self.values)
465 }
466}
467
468impl<T> IntoIterator for Merge<T> {
469 type Item = T;
470 type IntoIter = smallvec::IntoIter<[T; 1]>;
471
472 fn into_iter(self) -> Self::IntoIter {
473 self.values.into_iter()
474 }
475}
476
477impl<T> FromIterator<T> for MergeBuilder<T> {
478 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
479 let mut builder = Self::default();
480 builder.extend(iter);
481 builder
482 }
483}
484
485impl<T> Extend<T> for MergeBuilder<T> {
486 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
487 self.values.extend(iter);
488 }
489}
490
491impl<T> Merge<Option<T>> {
492 pub fn absent() -> Self {
494 Self::resolved(None)
495 }
496
497 pub fn normal(value: T) -> Self {
499 Self::resolved(Some(value))
500 }
501
502 pub fn is_absent(&self) -> bool {
504 matches!(self.as_resolved(), Some(None))
505 }
506
507 pub fn is_present(&self) -> bool {
509 !self.is_absent()
510 }
511
512 pub fn as_normal(&self) -> Option<&T> {
514 self.as_resolved()?.as_ref()
515 }
516
517 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
521 let mut removes = Vec::with_capacity(self.values.len() / 2);
523 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
524 let mut values = self.values.into_iter();
525 adds.extend(values.next().unwrap());
526 while let Some(remove) = values.next() {
527 removes.extend(remove);
528 adds.extend(values.next().unwrap());
529 }
530 (removes, adds)
531 }
532}
533
534impl<T: Clone> Merge<Option<&T>> {
535 pub fn cloned(&self) -> Merge<Option<T>> {
537 self.map(|value| value.cloned())
538 }
539}
540
541impl<T> Merge<Merge<T>> {
542 pub fn flatten(self) -> Merge<T> {
560 let mut outer_values = self.values.into_iter();
561 let mut result = outer_values.next().unwrap();
562 while let Some(mut remove) = outer_values.next() {
563 remove.values.rotate_left(1);
566 for i in 0..remove.values.len() / 2 {
567 remove.values.swap(i * 2, i * 2 + 1);
568 }
569 result.values.extend(remove.values);
570 let add = outer_values.next().unwrap();
571 result.values.extend(add.values);
572 }
573 result
574 }
575}
576
577impl<T: ContentHash> ContentHash for Merge<T> {
578 fn hash(&self, state: &mut impl DigestUpdate) {
579 self.values.hash(state);
580 }
581}
582
583pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
585
586pub type MergedTreeValue = Merge<Option<TreeValue>>;
593
594impl<T> Merge<Option<T>>
595where
596 T: Borrow<TreeValue>,
597{
598 pub fn is_tree(&self) -> bool {
600 self.is_present()
601 && self.iter().all(|value| {
602 matches!(
603 borrow_tree_value(value.as_ref()),
604 Some(TreeValue::Tree(_)) | None
605 )
606 })
607 }
608
609 pub fn is_file_like(&self) -> bool {
611 self.is_present() && !self.is_tree()
612 }
613
614 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
619 let file_ids = self
620 .try_map(|term| match borrow_tree_value(term.as_ref()) {
621 None => Ok(None),
622 Some(TreeValue::File {
623 id,
624 executable: _,
625 copy_id: _,
626 }) => Ok(Some(id.clone())),
627 _ => Err(()),
628 })
629 .ok()?;
630
631 Some(file_ids)
632 }
633
634 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
637 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
638 None => Ok(None),
639 Some(TreeValue::File {
640 id: _,
641 executable,
642 copy_id: _,
643 }) => Ok(Some(*executable)),
644 _ => Err(()),
645 })
646 .ok()
647 }
648
649 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
652 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
653 None => Ok(None),
654 Some(TreeValue::File {
655 id: _,
656 executable: _,
657 copy_id,
658 }) => Ok(Some(copy_id.clone())),
659 _ => Err(()),
660 })
661 .ok()
662 }
663
664 pub async fn to_tree_merge(
669 &self,
670 store: &Arc<Store>,
671 dir: &RepoPath,
672 ) -> BackendResult<Option<Merge<Tree>>> {
673 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
674 None => Ok(None),
675 Some(TreeValue::Tree(id)) => Ok(Some(id)),
676 Some(_) => Err(()),
677 });
678 if let Ok(tree_id_merge) = tree_id_merge {
679 Ok(Some(
680 tree_id_merge
681 .try_map_async(async |id| {
682 if let Some(id) = id {
683 store.get_tree_async(dir.to_owned(), id).await
684 } else {
685 Ok(Tree::empty(store.clone(), dir.to_owned()))
686 }
687 })
688 .await?,
689 ))
690 } else {
691 Ok(None)
692 }
693 }
694
695 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
701 assert_eq!(self.values.len(), file_ids.values.len());
702 let values = zip(self.iter(), file_ids.iter().cloned())
703 .map(
704 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
705 (
706 Some(TreeValue::File {
707 id: _,
708 executable,
709 copy_id,
710 }),
711 Some(id),
712 ) => Some(TreeValue::File {
713 id,
714 executable: *executable,
715 copy_id: copy_id.clone(),
716 }),
717 (None, None) => None,
718 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
719 },
720 )
721 .collect();
722 Merge { values }
723 }
724
725 pub fn describe(&self) -> String {
727 let mut buf = String::new();
728 writeln!(buf, "Conflict:").unwrap();
729 for term in self.removes().flatten() {
730 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
731 }
732 for term in self.adds().flatten() {
733 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
734 }
735 buf
736 }
737}
738
739fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
740 term.map(|value| value.borrow())
741}
742
743fn describe_conflict_term(value: &TreeValue) -> String {
744 match value {
745 TreeValue::File {
746 id,
747 executable: false,
748 copy_id: _,
749 } => {
750 format!("file with id {id}")
752 }
753 TreeValue::File {
754 id,
755 executable: true,
756 copy_id: _,
757 } => {
758 format!("executable file with id {id}")
760 }
761 TreeValue::Symlink(id) => {
762 format!("symlink with id {id}")
763 }
764 TreeValue::Tree(id) => {
765 format!("tree with id {id}")
766 }
767 TreeValue::GitSubmodule(id) => {
768 format!("Git submodule with id {id}")
769 }
770 }
771}
772
773impl Merge<Tree> {
774 pub fn dir(&self) -> &RepoPath {
776 debug_assert!(self.iter().map(|tree| tree.dir()).all_equal());
777 self.first().dir()
778 }
779
780 pub fn value(&self, basename: &RepoPathComponent) -> MergedTreeVal<'_> {
785 if let Some(tree) = self.as_resolved() {
786 return Merge::resolved(tree.value(basename));
787 }
788 let same_change = self.first().store().merge_options().same_change;
789 let value = self.map(|tree| tree.value(basename));
790 if let Some(resolved) = value.resolve_trivial(same_change) {
791 return Merge::resolved(*resolved);
792 }
793 value
794 }
795
796 pub async fn sub_tree(&self, name: &RepoPathComponent) -> BackendResult<Option<Self>> {
800 let store = self.first().store();
801 match self.value(name).into_resolved() {
802 Ok(Some(TreeValue::Tree(sub_tree_id))) => {
803 let subdir = self.dir().join(name);
804 Ok(Some(Self::resolved(
805 store.get_tree_async(subdir, sub_tree_id).await?,
806 )))
807 }
808 Ok(_) => Ok(None),
809 Err(merge) => {
810 if !merge.is_tree() {
811 return Ok(None);
812 }
813 let trees = merge
814 .try_map_async(async |value| match value {
815 Some(TreeValue::Tree(sub_tree_id)) => {
816 let subdir = self.dir().join(name);
817 store.get_tree_async(subdir, sub_tree_id).await
818 }
819 Some(_) => unreachable!(),
820 None => {
821 let subdir = self.dir().join(name);
822 Ok(Tree::empty(store.clone(), subdir))
823 }
824 })
825 .await?;
826 Ok(Some(trees))
827 }
828 }
829 }
830
831 pub async fn sub_tree_recursive(&self, path: &RepoPath) -> BackendResult<Option<Self>> {
833 let mut current_tree = self.clone();
834 for name in path.components() {
835 match current_tree.sub_tree(name).await? {
836 None => {
837 return Ok(None);
838 }
839 Some(sub_tree) => {
840 current_tree = sub_tree;
841 }
842 }
843 }
844 Ok(Some(current_tree))
845 }
846}
847
848#[cfg(test)]
849mod tests {
850 use test_case::test_case;
851
852 use super::*;
853
854 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
855 Merge::from_vec(terms.to_vec())
856 }
857
858 #[test_case(SameChange::Keep)]
859 #[test_case(SameChange::Accept)]
860 fn test_trivial_merge(same_change: SameChange) {
861 let accept_same_change = same_change == SameChange::Accept;
862 let merge = |values| trivial_merge(values, same_change);
863 assert_eq!(merge(&[0]), Some(&0));
864 assert_eq!(merge(&[0, 0, 0]), Some(&0));
865 assert_eq!(merge(&[0, 0, 1]), Some(&1));
866 assert_eq!(merge(&[0, 1, 0]), accept_same_change.then_some(&0));
867 assert_eq!(merge(&[0, 1, 1]), Some(&0));
868 assert_eq!(merge(&[0, 1, 2]), None);
869 assert_eq!(merge(&[0, 0, 0, 0, 0]), Some(&0));
870 assert_eq!(merge(&[0, 0, 0, 0, 1]), Some(&1));
871 assert_eq!(merge(&[0, 0, 0, 1, 0]), accept_same_change.then_some(&0));
872 assert_eq!(merge(&[0, 0, 0, 1, 1]), Some(&0));
873 assert_eq!(merge(&[0, 0, 0, 1, 2]), None);
874 assert_eq!(merge(&[0, 0, 1, 0, 0]), Some(&1));
875 assert_eq!(merge(&[0, 0, 1, 0, 1]), accept_same_change.then_some(&1));
876 assert_eq!(merge(&[0, 0, 1, 0, 2]), None);
877 assert_eq!(merge(&[0, 0, 1, 1, 0]), Some(&0));
878 assert_eq!(merge(&[0, 0, 1, 1, 1]), Some(&1));
879 assert_eq!(merge(&[0, 0, 1, 1, 2]), Some(&2));
880 assert_eq!(merge(&[0, 0, 1, 2, 0]), None);
881 assert_eq!(merge(&[0, 0, 1, 2, 1]), accept_same_change.then_some(&1));
882 assert_eq!(merge(&[0, 0, 1, 2, 2]), Some(&1));
883 assert_eq!(merge(&[0, 0, 1, 2, 3]), None);
884 assert_eq!(merge(&[0, 1, 0, 0, 0]), accept_same_change.then_some(&0));
885 assert_eq!(merge(&[0, 1, 0, 0, 1]), Some(&0));
886 assert_eq!(merge(&[0, 1, 0, 0, 2]), None);
887 assert_eq!(merge(&[0, 1, 0, 1, 0]), accept_same_change.then_some(&0));
888 assert_eq!(merge(&[0, 1, 0, 1, 1]), accept_same_change.then_some(&0));
889 assert_eq!(merge(&[0, 1, 0, 1, 2]), None);
890 assert_eq!(merge(&[0, 1, 0, 2, 0]), None);
891 assert_eq!(merge(&[0, 1, 0, 2, 1]), accept_same_change.then_some(&0));
892 assert_eq!(merge(&[0, 1, 0, 2, 2]), accept_same_change.then_some(&0));
893 assert_eq!(merge(&[0, 1, 0, 2, 3]), None);
894 assert_eq!(merge(&[0, 1, 1, 0, 0]), Some(&0));
895 assert_eq!(merge(&[0, 1, 1, 0, 1]), Some(&1));
896 assert_eq!(merge(&[0, 1, 1, 0, 2]), Some(&2));
897 assert_eq!(merge(&[0, 1, 1, 1, 0]), accept_same_change.then_some(&0));
898 assert_eq!(merge(&[0, 1, 1, 1, 1]), Some(&0));
899 assert_eq!(merge(&[0, 1, 1, 1, 2]), None);
900 assert_eq!(merge(&[0, 1, 1, 2, 0]), accept_same_change.then_some(&0));
901 assert_eq!(merge(&[0, 1, 1, 2, 1]), None);
902 assert_eq!(merge(&[0, 1, 1, 2, 2]), Some(&0));
903 assert_eq!(merge(&[0, 1, 1, 2, 3]), None);
904 assert_eq!(merge(&[0, 1, 2, 0, 0]), None);
905 assert_eq!(merge(&[0, 1, 2, 0, 1]), Some(&2));
906 assert_eq!(merge(&[0, 1, 2, 0, 2]), accept_same_change.then_some(&2));
907 assert_eq!(merge(&[0, 1, 2, 0, 3]), None);
908 assert_eq!(merge(&[0, 1, 2, 1, 0]), None);
909 assert_eq!(merge(&[0, 1, 2, 1, 1]), None);
910 assert_eq!(merge(&[0, 1, 2, 1, 2]), None);
911 assert_eq!(merge(&[0, 1, 2, 1, 3]), None);
912 assert_eq!(merge(&[0, 1, 2, 2, 0]), accept_same_change.then_some(&0));
913 assert_eq!(merge(&[0, 1, 2, 2, 1]), Some(&0));
914 assert_eq!(merge(&[0, 1, 2, 2, 2]), None);
915 assert_eq!(merge(&[0, 1, 2, 2, 3]), None);
916 assert_eq!(merge(&[0, 1, 2, 3, 0]), None);
917 assert_eq!(merge(&[0, 1, 2, 3, 1]), None);
918 assert_eq!(merge(&[0, 1, 2, 3, 2]), None);
919 assert_eq!(merge(&[0, 1, 2, 3, 3]), None);
920 assert_eq!(merge(&[0, 1, 2, 3, 4]), None);
921 }
922
923 #[test]
924 fn test_legacy_form_conversion() {
925 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
926 where
927 T: Clone + PartialEq + std::fmt::Debug,
928 {
929 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
930 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
931 }
932 test_equivalent(
934 (vec![], vec![0]),
935 Merge::from_removes_adds(vec![], vec![Some(0)]),
936 );
937 test_equivalent(
939 (vec![0], vec![1, 2]),
940 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
941 );
942 test_equivalent(
944 (vec![0], vec![1]),
945 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
946 );
947 test_equivalent(
949 (vec![], vec![0, 1]),
950 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
951 );
952 test_equivalent(
954 (vec![0, 1], vec![2, 3, 4]),
955 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
956 );
957 test_equivalent(
959 (vec![0, 1], vec![]),
960 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
961 );
962 }
963
964 #[test]
965 fn test_as_resolved() {
966 assert_eq!(
967 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
968 Some(&0)
969 );
970 assert_eq!(
972 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
973 None
974 );
975 }
976
977 #[test]
978 fn test_get_simplified_mapping() {
979 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
981 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
983 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
984 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
985 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
986 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
987 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
989 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
990 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
991 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
992 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
993 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
994 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
995 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
996 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
997 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
998 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
999 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
1000 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
1001 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1002 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
1003 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1004 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
1005 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1006 assert_eq!(
1007 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
1008 vec![0, 1, 2, 3, 4]
1009 );
1010 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1011 assert_eq!(
1012 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
1013 vec![0, 1, 2, 3, 4]
1014 );
1015 assert_eq!(
1016 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
1017 vec![0, 1, 2, 3, 4]
1018 );
1019 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1020 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
1021 assert_eq!(
1022 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
1023 vec![0, 1, 2, 3, 4]
1024 );
1025 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
1026 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
1027 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
1028 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1029 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
1030 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
1031 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1032 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
1033 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
1034 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
1035 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1036 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
1037 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1038 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
1039 assert_eq!(
1040 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
1041 vec![0, 1, 2, 3, 4]
1042 );
1043 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1044 assert_eq!(
1045 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
1046 vec![0, 1, 2, 3, 4]
1047 );
1048 assert_eq!(
1049 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
1050 vec![0, 1, 2, 3, 4]
1051 );
1052 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
1053 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
1054 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
1055 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
1056 assert_eq!(
1057 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
1058 vec![0, 1, 2, 3, 4]
1059 );
1060 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1061 assert_eq!(
1062 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
1063 vec![0, 1, 2, 3, 4]
1064 );
1065 assert_eq!(
1066 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
1067 vec![0, 3, 4, 5, 2]
1068 );
1069 assert_eq!(
1070 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
1071 vec![0, 1, 2, 3, 4]
1072 );
1073 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
1074 }
1075
1076 #[test]
1077 fn test_simplify() {
1078 assert_eq!(c(&[0]).simplify(), c(&[0]));
1080 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
1082 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
1083 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
1084 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
1085 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
1086 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
1088 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
1089 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
1090 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
1091 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
1092 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
1093 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
1094 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
1095 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
1096 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
1097 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
1098 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
1099 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
1100 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
1101 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
1102 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
1103 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
1104 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
1105 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
1106 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
1107 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1108 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1109 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1110 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1111 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1112 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1113 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1114 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1115 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1116 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1117 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1118 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1119 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1120 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1121 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1122 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1123 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1124 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1125 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1126 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1127 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1128 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1129 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1130 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1131 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1132 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1133 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1134 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1135 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1136 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1137 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1138 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1139 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1140 }
1141
1142 #[test]
1143 fn test_update_from_simplified() {
1144 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1146 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1148 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1149 assert_eq!(
1150 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1151 c(&[2, 1, 3])
1152 );
1153 assert_eq!(
1155 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1156 c(&[0, 0, 0, 0, 1])
1157 );
1158 assert_eq!(
1159 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1160 c(&[0, 0, 2, 3, 1])
1161 );
1162 assert_eq!(
1163 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1164 c(&[0, 3, 1, 0, 2])
1165 );
1166 assert_eq!(
1167 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1168 c(&[3, 1, 4, 2, 5])
1169 );
1170
1171 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1172 assert_eq!(
1175 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1176 c(&[0, 0, 10, 1, 11, 2, 4])
1177 );
1178 }
1179
1180 #[test]
1181 fn test_merge_invariants() {
1182 fn check_invariants(terms: &[u32]) {
1183 let merge = Merge::from_vec(terms.to_vec());
1184 assert_eq!(
1186 merge.simplify().simplify(),
1187 merge.simplify(),
1188 "simplify() not idempotent for {merge:?}"
1189 );
1190 assert_eq!(
1192 merge.simplify().resolve_trivial(SameChange::Accept),
1193 merge.resolve_trivial(SameChange::Accept),
1194 "simplify() changed result of resolve_trivial() for {merge:?}"
1195 );
1196 }
1197 check_invariants(&[0]);
1199 for i in 0..=1 {
1200 for j in 0..=i + 1 {
1201 check_invariants(&[i, 0, j]);
1203 for k in 0..=j + 1 {
1204 for l in 0..=k + 1 {
1205 check_invariants(&[0, i, j, k, l]);
1207 }
1208 }
1209 }
1210 }
1211 }
1212
1213 #[test]
1214 fn test_swap_remove() {
1215 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1216 assert_eq!(x.swap_remove(0, 1), (1, 2));
1217 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1218 assert_eq!(x.swap_remove(1, 0), (3, 0));
1219 assert_eq!(x, c(&[4, 5, 6]));
1220 assert_eq!(x.swap_remove(0, 1), (5, 6));
1221 assert_eq!(x, c(&[4]));
1222 }
1223
1224 #[test]
1225 fn test_pad_to() {
1226 let mut x = c(&[1]);
1227 x.pad_to(3, &2);
1228 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1229 x.pad_to(1, &3);
1231 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1232 }
1233
1234 #[test]
1235 fn test_iter() {
1236 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1238 assert_eq!(
1240 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1241 vec![&1, &2, &3, &4, &5]
1242 );
1243 }
1244
1245 #[test]
1246 fn test_from_iter() {
1247 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1249 assert_eq!(
1251 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1252 c(&[1, 2, 3, 4, 5])
1253 );
1254 }
1255
1256 #[test]
1257 #[should_panic]
1258 fn test_from_iter_empty() {
1259 MergeBuilder::from_iter([1; 0]).build();
1260 }
1261
1262 #[test]
1263 #[should_panic]
1264 fn test_from_iter_even() {
1265 MergeBuilder::from_iter([1, 2]).build();
1266 }
1267
1268 #[test]
1269 fn test_extend() {
1270 let mut builder: MergeBuilder<i32> = Default::default();
1272 builder.extend([1]);
1273 assert_eq!(builder.build(), c(&[1]));
1274 let mut builder: MergeBuilder<i32> = Default::default();
1276 builder.extend([1, 2]);
1277 builder.extend([3, 4, 5]);
1278 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1279 }
1280
1281 #[test]
1282 fn test_map() {
1283 fn increment(i: &i32) -> i32 {
1284 i + 1
1285 }
1286 assert_eq!(c(&[1]).map(increment), c(&[2]));
1288 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1290 }
1291
1292 #[test]
1293 fn test_try_map() {
1294 fn sqrt(i: &i32) -> Result<i32, ()> {
1295 if *i >= 0 {
1296 Ok((*i as f64).sqrt() as i32)
1297 } else {
1298 Err(())
1299 }
1300 }
1301 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1303 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1304 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1306 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1307 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1308 }
1309
1310 #[test]
1311 fn test_flatten() {
1312 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1314 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1316 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1318 assert_eq!(
1320 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1321 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1322 );
1323 }
1324}