1use std::borrow::Borrow;
19use std::collections::HashMap;
20use std::fmt::Debug;
21use std::fmt::Formatter;
22use std::fmt::Write as _;
23use std::hash::Hash;
24use std::iter;
25use std::iter::zip;
26use std::ops::Deref;
27use std::slice;
28use std::sync::Arc;
29
30use futures::future::try_join_all;
31use itertools::Itertools as _;
32use smallvec::SmallVec;
33use smallvec::smallvec;
34use smallvec::smallvec_inline;
35
36use crate::backend::BackendResult;
37use crate::backend::CopyId;
38use crate::backend::FileId;
39use crate::backend::TreeValue;
40use crate::conflict_labels::ConflictLabels;
41use crate::content_hash::ContentHash;
42use crate::content_hash::DigestUpdate;
43use crate::repo_path::RepoPath;
44use crate::repo_path::RepoPathComponent;
45use crate::store::Store;
46use crate::tree::Tree;
47
48#[derive(Copy, Clone, Debug, PartialEq, Eq)]
53pub struct Diff<T> {
54 pub before: T,
56 pub after: T,
58}
59
60impl<T> Diff<T> {
61 pub fn new(before: T, after: T) -> Self {
63 Self { before, after }
64 }
65
66 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Diff<U> {
68 Diff {
69 before: f(self.before),
70 after: f(self.after),
71 }
72 }
73
74 pub fn zip<U>(self, other: Diff<U>) -> Diff<(T, U)> {
76 Diff {
77 before: (self.before, other.before),
78 after: (self.after, other.after),
79 }
80 }
81
82 pub fn invert(self) -> Self {
84 Self {
85 before: self.after,
86 after: self.before,
87 }
88 }
89
90 pub fn as_ref(&self) -> Diff<&T> {
92 Diff {
93 before: &self.before,
94 after: &self.after,
95 }
96 }
97
98 pub fn as_deref(&self) -> Diff<&T::Target>
101 where
102 T: Deref,
103 {
104 self.as_ref().map(Deref::deref)
105 }
106
107 pub fn into_array(self) -> [T; 2] {
109 [self.before, self.after]
110 }
111}
112
113impl<T: Eq> Diff<T> {
114 pub fn is_changed(&self) -> bool {
117 self.before != self.after
118 }
119}
120
121#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize)]
123#[serde(rename_all = "kebab-case")]
124pub enum SameChange {
125 Keep,
127 Accept,
134}
135
136pub fn trivial_merge<T>(values: &[T], same_change: SameChange) -> Option<&T>
139where
140 T: Eq + Hash,
141{
142 assert!(
143 values.len() % 2 == 1,
144 "trivial_merge() requires an odd number of terms"
145 );
146 if let [add] = values {
148 return Some(add);
149 } else if let [add0, remove, add1] = values {
150 return if add0 == add1 && same_change == SameChange::Accept {
151 Some(add0)
152 } else if add0 == remove {
153 Some(add1)
154 } else if add1 == remove {
155 Some(add0)
156 } else {
157 None
158 };
159 }
160
161 let mut counts: HashMap<&T, i32> = HashMap::new();
165 for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
166 counts.entry(value).and_modify(|e| *e += n).or_insert(n);
167 }
168
169 counts.retain(|_, count| *count != 0);
172 if counts.len() == 1 {
173 let (value, count) = counts.into_iter().next().unwrap();
175 assert_eq!(count, 1);
176 Some(value)
177 } else if counts.len() == 2 && same_change == SameChange::Accept {
178 let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
180 assert_eq!(count1 + count2, 1);
181 if count1 > 0 {
182 Some(value1)
183 } else {
184 Some(value2)
185 }
186 } else {
187 None
188 }
189}
190
191#[derive(PartialEq, Eq, Hash, Clone, serde::Serialize)]
197#[serde(transparent)]
198pub struct Merge<T> {
199 values: SmallVec<[T; 1]>,
201}
202
203impl<T: Debug> Debug for Merge<T> {
204 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
205 if let Some(value) = self.as_resolved() {
208 f.debug_tuple("Resolved").field(value).finish()
209 } else {
210 f.debug_tuple("Conflicted").field(&self.values).finish()
211 }
212 }
213}
214
215impl<T> Merge<T> {
216 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
219 let values = values.into();
220 assert!(values.len() % 2 != 0, "must have an odd number of terms");
221 Self { values }
222 }
223
224 pub fn from_removes_adds(
226 removes: impl IntoIterator<Item = T>,
227 adds: impl IntoIterator<Item = T>,
228 ) -> Self {
229 let removes = removes.into_iter();
230 let mut adds = adds.into_iter();
231 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
232 values.push(adds.next().expect("must have at least one add"));
233 for diff in removes.zip_longest(adds) {
234 let (remove, add) = diff.both().expect("must have one more adds than removes");
235 values.extend([remove, add]);
236 }
237 Self { values }
238 }
239
240 pub fn from_diffs(first_side: T, diffs: impl IntoIterator<Item = Diff<T>>) -> Self {
243 let values = iter::once(first_side)
244 .chain(diffs.into_iter().flat_map(Diff::into_array))
245 .collect();
246 Self { values }
247 }
248
249 pub const fn resolved(value: T) -> Self {
251 Self {
252 values: smallvec_inline![value],
253 }
254 }
255
256 pub fn repeated(value: T, num_sides: usize) -> Self
258 where
259 T: Clone,
260 {
261 Self {
262 values: smallvec![value; num_sides * 2 - 1],
263 }
264 }
265
266 pub fn from_legacy_form(
269 removes: impl IntoIterator<Item = T>,
270 adds: impl IntoIterator<Item = T>,
271 ) -> Merge<Option<T>> {
272 let removes = removes.into_iter();
273 let mut adds = adds.into_iter().fuse();
274 let mut values = smallvec_inline![adds.next()];
275 for diff in removes.zip_longest(adds) {
276 let (remove, add) = diff.map_any(Some, Some).or_default();
277 values.extend([remove, add]);
278 }
279 Merge { values }
280 }
281
282 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
284 self.values[1..].iter().step_by(2)
285 }
286
287 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
289 self.values.iter().step_by(2)
290 }
291
292 pub fn into_removes_adds(
294 self,
295 ) -> (
296 impl ExactSizeIterator<Item = T>,
297 impl ExactSizeIterator<Item = T>,
298 ) {
299 let (removes, adds): (Vec<_>, Vec<_>) = self
300 .values
301 .into_iter()
302 .enumerate()
303 .partition(|(n, _)| *n % 2 == 1);
304 (
305 removes.into_iter().map(|(_, item)| item),
306 adds.into_iter().map(|(_, item)| item),
307 )
308 }
309
310 pub fn first(&self) -> &T {
312 &self.values[0]
313 }
314
315 pub fn get_remove(&self, index: usize) -> Option<&T> {
318 self.values.get(index * 2 + 1)
319 }
320
321 pub fn get_add(&self, index: usize) -> Option<&T> {
325 self.values.get(index * 2)
326 }
327
328 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
331 let add = self.values.swap_remove(add_index * 2);
333 let remove = self.values.swap_remove(remove_index * 2 + 1);
334 (remove, add)
335 }
336
337 pub fn num_sides(&self) -> usize {
339 self.values.len() / 2 + 1
340 }
341
342 pub fn is_resolved(&self) -> bool {
344 self.values.len() == 1
345 }
346
347 pub fn as_resolved(&self) -> Option<&T> {
350 if let [value] = &self.values[..] {
351 Some(value)
352 } else {
353 None
354 }
355 }
356
357 pub fn into_resolved(mut self) -> Result<T, Self> {
360 if self.values.len() == 1 {
361 Ok(self.values.pop().unwrap())
362 } else {
363 Err(self)
364 }
365 }
366
367 fn get_simplified_mapping(&self) -> Vec<usize>
373 where
374 T: PartialEq,
375 {
376 let unsimplified_len = self.values.len();
377 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
378
379 let mut add_index = 0;
380 while add_index < simplified_to_original_indices.len() {
381 let add = &self.values[simplified_to_original_indices[add_index]];
382 let mut remove_indices = simplified_to_original_indices
383 .iter()
384 .enumerate()
385 .skip(1)
386 .step_by(2);
387 if let Some((remove_index, _)) = remove_indices
388 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
389 {
390 simplified_to_original_indices.swap(remove_index + 1, add_index);
393 simplified_to_original_indices.drain(remove_index..remove_index + 2);
394 } else {
395 add_index += 2;
396 }
397 }
398
399 simplified_to_original_indices
400 }
401
402 #[must_use]
404 fn apply_simplified_mapping(&self, mapping: &[usize]) -> Self
405 where
406 T: Clone,
407 {
408 let values = mapping
410 .iter()
411 .map(|index| self.values[*index].clone())
412 .collect();
413 Self { values }
414 }
415
416 #[must_use]
419 pub fn simplify(&self) -> Self
420 where
421 T: PartialEq + Clone,
422 {
423 let mapping = self.get_simplified_mapping();
424 self.apply_simplified_mapping(&mapping)
425 }
426
427 #[must_use]
429 pub fn simplify_by<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Self
430 where
431 T: Clone,
432 U: PartialEq,
433 {
434 let mapping = self.map(f).get_simplified_mapping();
435 self.apply_simplified_mapping(&mapping)
436 }
437
438 pub fn update_from_simplified(mut self, simplified: Self) -> Self
440 where
441 T: PartialEq,
442 {
443 let mapping = self.get_simplified_mapping();
444 assert_eq!(mapping.len(), simplified.values.len());
445 for (index, value) in mapping.into_iter().zip(simplified.values) {
446 self.values[index] = value;
447 }
448 self
449 }
450
451 pub fn resolve_trivial(&self, same_change: SameChange) -> Option<&T>
454 where
455 T: Eq + Hash,
456 {
457 trivial_merge(&self.values, same_change)
458 }
459
460 pub fn pad_to(&mut self, num_sides: usize, value: &T)
463 where
464 T: Clone,
465 {
466 if num_sides <= self.num_sides() {
467 return;
468 }
469 self.values.resize(num_sides * 2 - 1, value.clone());
470 }
471
472 pub fn as_slice(&self) -> &[T] {
476 &self.values
477 }
478
479 pub fn iter(&self) -> slice::Iter<'_, T> {
483 self.values.iter()
484 }
485
486 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
488 self.values.iter_mut()
489 }
490
491 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
493 let values = self.values.iter().map(f).collect();
494 Merge { values }
495 }
496
497 pub fn into_map<U>(self, f: impl FnMut(T) -> U) -> Merge<U> {
500 let values = self.values.into_iter().map(f).collect();
501 Merge { values }
502 }
503
504 pub fn try_map<'a, U, E>(
507 &'a self,
508 f: impl FnMut(&'a T) -> Result<U, E>,
509 ) -> Result<Merge<U>, E> {
510 let values = self.values.iter().map(f).try_collect()?;
511 Ok(Merge { values })
512 }
513
514 pub async fn try_map_async<'a, F, U, E>(
518 &'a self,
519 f: impl FnMut(&'a T) -> F,
520 ) -> Result<Merge<U>, E>
521 where
522 F: Future<Output = Result<U, E>>,
523 {
524 let values = try_join_all(self.values.iter().map(f)).await?;
525 Ok(Merge {
526 values: values.into(),
527 })
528 }
529
530 pub fn as_ref(&self) -> Merge<&T> {
532 let values = self.values.iter().collect();
533 Merge { values }
534 }
535
536 pub fn zip<U>(self, other: Merge<U>) -> Merge<(T, U)> {
539 assert_eq!(self.values.len(), other.values.len());
540 let values = self.values.into_iter().zip(other.values).collect();
541 Merge { values }
542 }
543}
544
545impl<T, U> Merge<(T, U)> {
546 pub fn unzip(self) -> (Merge<T>, Merge<U>) {
548 let (left, right) = self.values.into_iter().unzip();
549 (Merge { values: left }, Merge { values: right })
550 }
551}
552
553impl<T> Merge<&'_ T> {
554 pub fn cloned(&self) -> Merge<T>
556 where
557 T: Clone,
558 {
559 self.map(|&term| term.clone())
560 }
561}
562
563#[derive(Clone, Debug, PartialEq, Eq)]
572pub struct MergeBuilder<T> {
573 values: SmallVec<[T; 1]>,
574}
575
576impl<T> Default for MergeBuilder<T> {
577 fn default() -> Self {
578 Self {
579 values: Default::default(),
580 }
581 }
582}
583
584impl<T> MergeBuilder<T> {
585 pub fn build(self) -> Merge<T> {
588 Merge::from_vec(self.values)
589 }
590}
591
592impl<T> IntoIterator for Merge<T> {
593 type Item = T;
594 type IntoIter = smallvec::IntoIter<[T; 1]>;
595
596 fn into_iter(self) -> Self::IntoIter {
597 self.values.into_iter()
598 }
599}
600
601impl<'a, T> IntoIterator for &'a Merge<T> {
602 type Item = &'a T;
603 type IntoIter = slice::Iter<'a, T>;
604
605 fn into_iter(self) -> Self::IntoIter {
606 self.iter()
607 }
608}
609
610impl<'a, T> IntoIterator for &'a mut Merge<T> {
611 type Item = &'a mut T;
612 type IntoIter = slice::IterMut<'a, T>;
613
614 fn into_iter(self) -> Self::IntoIter {
615 self.iter_mut()
616 }
617}
618
619impl<T> FromIterator<T> for MergeBuilder<T> {
620 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
621 let mut builder = Self::default();
622 builder.extend(iter);
623 builder
624 }
625}
626
627impl<T> Extend<T> for MergeBuilder<T> {
628 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
629 self.values.extend(iter);
630 }
631}
632
633impl<T> Merge<Option<T>> {
634 pub fn absent() -> Self {
636 Self::resolved(None)
637 }
638
639 pub fn normal(value: T) -> Self {
641 Self::resolved(Some(value))
642 }
643
644 pub fn is_absent(&self) -> bool {
646 matches!(self.as_resolved(), Some(None))
647 }
648
649 pub fn is_present(&self) -> bool {
651 !self.is_absent()
652 }
653
654 pub fn as_normal(&self) -> Option<&T> {
656 self.as_resolved()?.as_ref()
657 }
658
659 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
663 let mut removes = Vec::with_capacity(self.values.len() / 2);
665 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
666 let mut values = self.values.into_iter();
667 adds.extend(values.next().unwrap());
668 while let Some(remove) = values.next() {
669 removes.extend(remove);
670 adds.extend(values.next().unwrap());
671 }
672 (removes, adds)
673 }
674}
675
676impl<T: Clone> Merge<Option<&T>> {
677 pub fn cloned(&self) -> Merge<Option<T>> {
679 self.map(|value| value.cloned())
680 }
681}
682
683impl<T> Merge<Merge<T>> {
684 pub fn flatten(self) -> Merge<T> {
702 let mut outer_values = self.values.into_iter();
703 let mut result = outer_values.next().unwrap();
704 while let Some(mut remove) = outer_values.next() {
705 remove.values.rotate_left(1);
708 for i in 0..remove.values.len() / 2 {
709 remove.values.swap(i * 2, i * 2 + 1);
710 }
711 result.values.extend(remove.values);
712 let add = outer_values.next().unwrap();
713 result.values.extend(add.values);
714 }
715 result
716 }
717}
718
719impl<T: ContentHash> ContentHash for Merge<T> {
720 fn hash(&self, state: &mut impl DigestUpdate) {
721 self.values.hash(state);
722 }
723}
724
725pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
727
728pub type MergedTreeValue = Merge<Option<TreeValue>>;
735
736impl<T> Merge<Option<T>>
737where
738 T: Borrow<TreeValue>,
739{
740 pub fn is_tree(&self) -> bool {
742 self.is_present()
743 && self.iter().all(|value| {
744 matches!(
745 borrow_tree_value(value.as_ref()),
746 Some(TreeValue::Tree(_)) | None
747 )
748 })
749 }
750
751 pub fn is_file_like(&self) -> bool {
753 self.is_present() && !self.is_tree()
754 }
755
756 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
761 let file_ids = self
762 .try_map(|term| match borrow_tree_value(term.as_ref()) {
763 None => Ok(None),
764 Some(TreeValue::File {
765 id,
766 executable: _,
767 copy_id: _,
768 }) => Ok(Some(id.clone())),
769 _ => Err(()),
770 })
771 .ok()?;
772
773 Some(file_ids)
774 }
775
776 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
779 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
780 None => Ok(None),
781 Some(TreeValue::File {
782 id: _,
783 executable,
784 copy_id: _,
785 }) => Ok(Some(*executable)),
786 _ => Err(()),
787 })
788 .ok()
789 }
790
791 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
794 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
795 None => Ok(None),
796 Some(TreeValue::File {
797 id: _,
798 executable: _,
799 copy_id,
800 }) => Ok(Some(copy_id.clone())),
801 _ => Err(()),
802 })
803 .ok()
804 }
805
806 pub async fn to_tree_merge(
811 &self,
812 store: &Arc<Store>,
813 dir: &RepoPath,
814 ) -> BackendResult<Option<Merge<Tree>>> {
815 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
816 None => Ok(None),
817 Some(TreeValue::Tree(id)) => Ok(Some(id)),
818 Some(_) => Err(()),
819 });
820 if let Ok(tree_id_merge) = tree_id_merge {
821 Ok(Some(
822 tree_id_merge
823 .try_map_async(async |id| {
824 if let Some(id) = id {
825 store.get_tree(dir.to_owned(), id).await
826 } else {
827 Ok(Tree::empty(store.clone(), dir.to_owned()))
828 }
829 })
830 .await?,
831 ))
832 } else {
833 Ok(None)
834 }
835 }
836
837 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
843 assert_eq!(self.values.len(), file_ids.values.len());
844 let values = zip(self, file_ids.iter().cloned())
845 .map(
846 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
847 (
848 Some(TreeValue::File {
849 id: _,
850 executable,
851 copy_id,
852 }),
853 Some(id),
854 ) => Some(TreeValue::File {
855 id,
856 executable: *executable,
857 copy_id: copy_id.clone(),
858 }),
859 (None, None) => None,
860 (None, Some(id)) => Some(TreeValue::File {
864 id,
865 executable: false,
866 copy_id: CopyId::placeholder(),
867 }),
868 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
869 },
870 )
871 .collect();
872 Merge { values }
873 }
874
875 pub fn describe(&self, labels: &ConflictLabels) -> String {
877 let mut buf = String::new();
878 writeln!(buf, "Conflict:").unwrap();
879 for (term, label) in self
880 .removes()
881 .enumerate()
882 .filter_map(|(i, term)| term.as_ref().map(|term| (term, labels.get_remove(i))))
883 {
884 write!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
885 if let Some(label) = label {
886 write!(buf, " ({label})").unwrap();
887 }
888 buf.push('\n');
889 }
890 for (term, label) in self
891 .adds()
892 .enumerate()
893 .filter_map(|(i, term)| term.as_ref().map(|term| (term, labels.get_add(i))))
894 {
895 write!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
896 if let Some(label) = label {
897 write!(buf, " ({label})").unwrap();
898 }
899 buf.push('\n');
900 }
901 buf
902 }
903}
904
905fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
906 term.map(|value| value.borrow())
907}
908
909fn describe_conflict_term(value: &TreeValue) -> String {
910 match value {
911 TreeValue::File {
912 id,
913 executable: false,
914 copy_id: _,
915 } => {
916 format!("file with id {id}")
918 }
919 TreeValue::File {
920 id,
921 executable: true,
922 copy_id: _,
923 } => {
924 format!("executable file with id {id}")
926 }
927 TreeValue::Symlink(id) => {
928 format!("symlink with id {id}")
929 }
930 TreeValue::Tree(id) => {
931 format!("tree with id {id}")
932 }
933 TreeValue::GitSubmodule(id) => {
934 format!("Git submodule with id {id}")
935 }
936 }
937}
938
939impl Merge<Tree> {
940 pub fn dir(&self) -> &RepoPath {
942 debug_assert!(self.iter().map(|tree| tree.dir()).all_equal());
943 self.first().dir()
944 }
945
946 pub fn value(&self, basename: &RepoPathComponent) -> MergedTreeVal<'_> {
951 if let Some(tree) = self.as_resolved() {
952 return Merge::resolved(tree.value(basename));
953 }
954 let same_change = self.first().store().merge_options().same_change;
955 let value = self.map(|tree| tree.value(basename));
956 if let Some(resolved) = value.resolve_trivial(same_change) {
957 return Merge::resolved(*resolved);
958 }
959 value
960 }
961
962 pub async fn sub_tree(&self, name: &RepoPathComponent) -> BackendResult<Option<Self>> {
966 let store = self.first().store();
967 match self.value(name).into_resolved() {
968 Ok(Some(TreeValue::Tree(sub_tree_id))) => {
969 let subdir = self.dir().join(name);
970 Ok(Some(Self::resolved(
971 store.get_tree(subdir, sub_tree_id).await?,
972 )))
973 }
974 Ok(_) => Ok(None),
975 Err(merge) => {
976 if !merge.is_tree() {
977 return Ok(None);
978 }
979 let trees = merge
980 .try_map_async(async |value| match value {
981 Some(TreeValue::Tree(sub_tree_id)) => {
982 let subdir = self.dir().join(name);
983 store.get_tree(subdir, sub_tree_id).await
984 }
985 Some(_) => unreachable!(),
986 None => {
987 let subdir = self.dir().join(name);
988 Ok(Tree::empty(store.clone(), subdir))
989 }
990 })
991 .await?;
992 Ok(Some(trees))
993 }
994 }
995 }
996
997 pub async fn sub_tree_recursive(&self, path: &RepoPath) -> BackendResult<Option<Self>> {
999 let mut current_tree = self.clone();
1000 for name in path.components() {
1001 match current_tree.sub_tree(name).await? {
1002 None => {
1003 return Ok(None);
1004 }
1005 Some(sub_tree) => {
1006 current_tree = sub_tree;
1007 }
1008 }
1009 }
1010 Ok(Some(current_tree))
1011 }
1012}
1013
1014#[cfg(test)]
1015mod tests {
1016 use test_case::test_case;
1017
1018 use super::*;
1019
1020 #[test]
1021 fn test_diff_map() {
1022 let diff = Diff::new(1, 2);
1023 assert_eq!(diff.map(|x| x + 2), Diff::new(3, 4));
1024 }
1025
1026 #[test]
1027 fn test_diff_zip() {
1028 let diff1 = Diff::new(1, 2);
1029 let diff2 = Diff::new(3, 4);
1030 assert_eq!(diff1.zip(diff2), Diff::new((1, 3), (2, 4)));
1031 }
1032
1033 #[test]
1034 fn test_diff_invert() {
1035 let diff = Diff::new(1, 2);
1036 assert_eq!(diff.invert(), Diff::new(2, 1));
1037 }
1038
1039 #[test]
1040 fn test_diff_as_ref() {
1041 let diff = Diff::new(1, 2);
1042 assert_eq!(diff.as_ref(), Diff::new(&1, &2));
1043 }
1044
1045 #[test]
1046 fn test_diff_into_array() {
1047 let diff = Diff::new(1, 2);
1048 assert_eq!(diff.into_array(), [1, 2]);
1049 }
1050
1051 #[test]
1052 fn test_merge_from_diffs() {
1053 assert_eq!(Merge::from_diffs(1, []), Merge::resolved(1));
1054 assert_eq!(
1055 Merge::from_diffs(1, [Diff::new(2, 3)]),
1056 Merge::from_vec(vec![1, 2, 3])
1057 );
1058 assert_eq!(
1059 Merge::from_diffs(1, [Diff::new(2, 3), Diff::new(4, 5)]),
1060 Merge::from_vec(vec![1, 2, 3, 4, 5])
1061 );
1062 }
1063
1064 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
1065 Merge::from_vec(terms.to_vec())
1066 }
1067
1068 #[test_case(SameChange::Keep)]
1069 #[test_case(SameChange::Accept)]
1070 fn test_trivial_merge(same_change: SameChange) {
1071 let accept_same_change = same_change == SameChange::Accept;
1072 let merge = |values| trivial_merge(values, same_change);
1073 assert_eq!(merge(&[0]), Some(&0));
1074 assert_eq!(merge(&[0, 0, 0]), Some(&0));
1075 assert_eq!(merge(&[0, 0, 1]), Some(&1));
1076 assert_eq!(merge(&[0, 1, 0]), accept_same_change.then_some(&0));
1077 assert_eq!(merge(&[0, 1, 1]), Some(&0));
1078 assert_eq!(merge(&[0, 1, 2]), None);
1079 assert_eq!(merge(&[0, 0, 0, 0, 0]), Some(&0));
1080 assert_eq!(merge(&[0, 0, 0, 0, 1]), Some(&1));
1081 assert_eq!(merge(&[0, 0, 0, 1, 0]), accept_same_change.then_some(&0));
1082 assert_eq!(merge(&[0, 0, 0, 1, 1]), Some(&0));
1083 assert_eq!(merge(&[0, 0, 0, 1, 2]), None);
1084 assert_eq!(merge(&[0, 0, 1, 0, 0]), Some(&1));
1085 assert_eq!(merge(&[0, 0, 1, 0, 1]), accept_same_change.then_some(&1));
1086 assert_eq!(merge(&[0, 0, 1, 0, 2]), None);
1087 assert_eq!(merge(&[0, 0, 1, 1, 0]), Some(&0));
1088 assert_eq!(merge(&[0, 0, 1, 1, 1]), Some(&1));
1089 assert_eq!(merge(&[0, 0, 1, 1, 2]), Some(&2));
1090 assert_eq!(merge(&[0, 0, 1, 2, 0]), None);
1091 assert_eq!(merge(&[0, 0, 1, 2, 1]), accept_same_change.then_some(&1));
1092 assert_eq!(merge(&[0, 0, 1, 2, 2]), Some(&1));
1093 assert_eq!(merge(&[0, 0, 1, 2, 3]), None);
1094 assert_eq!(merge(&[0, 1, 0, 0, 0]), accept_same_change.then_some(&0));
1095 assert_eq!(merge(&[0, 1, 0, 0, 1]), Some(&0));
1096 assert_eq!(merge(&[0, 1, 0, 0, 2]), None);
1097 assert_eq!(merge(&[0, 1, 0, 1, 0]), accept_same_change.then_some(&0));
1098 assert_eq!(merge(&[0, 1, 0, 1, 1]), accept_same_change.then_some(&0));
1099 assert_eq!(merge(&[0, 1, 0, 1, 2]), None);
1100 assert_eq!(merge(&[0, 1, 0, 2, 0]), None);
1101 assert_eq!(merge(&[0, 1, 0, 2, 1]), accept_same_change.then_some(&0));
1102 assert_eq!(merge(&[0, 1, 0, 2, 2]), accept_same_change.then_some(&0));
1103 assert_eq!(merge(&[0, 1, 0, 2, 3]), None);
1104 assert_eq!(merge(&[0, 1, 1, 0, 0]), Some(&0));
1105 assert_eq!(merge(&[0, 1, 1, 0, 1]), Some(&1));
1106 assert_eq!(merge(&[0, 1, 1, 0, 2]), Some(&2));
1107 assert_eq!(merge(&[0, 1, 1, 1, 0]), accept_same_change.then_some(&0));
1108 assert_eq!(merge(&[0, 1, 1, 1, 1]), Some(&0));
1109 assert_eq!(merge(&[0, 1, 1, 1, 2]), None);
1110 assert_eq!(merge(&[0, 1, 1, 2, 0]), accept_same_change.then_some(&0));
1111 assert_eq!(merge(&[0, 1, 1, 2, 1]), None);
1112 assert_eq!(merge(&[0, 1, 1, 2, 2]), Some(&0));
1113 assert_eq!(merge(&[0, 1, 1, 2, 3]), None);
1114 assert_eq!(merge(&[0, 1, 2, 0, 0]), None);
1115 assert_eq!(merge(&[0, 1, 2, 0, 1]), Some(&2));
1116 assert_eq!(merge(&[0, 1, 2, 0, 2]), accept_same_change.then_some(&2));
1117 assert_eq!(merge(&[0, 1, 2, 0, 3]), None);
1118 assert_eq!(merge(&[0, 1, 2, 1, 0]), None);
1119 assert_eq!(merge(&[0, 1, 2, 1, 1]), None);
1120 assert_eq!(merge(&[0, 1, 2, 1, 2]), None);
1121 assert_eq!(merge(&[0, 1, 2, 1, 3]), None);
1122 assert_eq!(merge(&[0, 1, 2, 2, 0]), accept_same_change.then_some(&0));
1123 assert_eq!(merge(&[0, 1, 2, 2, 1]), Some(&0));
1124 assert_eq!(merge(&[0, 1, 2, 2, 2]), None);
1125 assert_eq!(merge(&[0, 1, 2, 2, 3]), None);
1126 assert_eq!(merge(&[0, 1, 2, 3, 0]), None);
1127 assert_eq!(merge(&[0, 1, 2, 3, 1]), None);
1128 assert_eq!(merge(&[0, 1, 2, 3, 2]), None);
1129 assert_eq!(merge(&[0, 1, 2, 3, 3]), None);
1130 assert_eq!(merge(&[0, 1, 2, 3, 4]), None);
1131 }
1132
1133 #[test]
1134 fn test_legacy_form_conversion() {
1135 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
1136 where
1137 T: Clone + PartialEq + std::fmt::Debug,
1138 {
1139 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
1140 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
1141 }
1142 test_equivalent(
1144 (vec![], vec![0]),
1145 Merge::from_removes_adds(vec![], vec![Some(0)]),
1146 );
1147 test_equivalent(
1149 (vec![0], vec![1, 2]),
1150 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
1151 );
1152 test_equivalent(
1154 (vec![0], vec![1]),
1155 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
1156 );
1157 test_equivalent(
1159 (vec![], vec![0, 1]),
1160 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
1161 );
1162 test_equivalent(
1164 (vec![0, 1], vec![2, 3, 4]),
1165 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
1166 );
1167 test_equivalent(
1169 (vec![0, 1], vec![]),
1170 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
1171 );
1172 }
1173
1174 #[test]
1175 fn test_as_resolved() {
1176 assert_eq!(
1177 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
1178 Some(&0)
1179 );
1180 assert_eq!(
1182 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
1183 None
1184 );
1185 }
1186
1187 #[test]
1188 fn test_get_simplified_mapping() {
1189 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
1191 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
1193 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
1194 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
1195 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
1196 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
1197 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
1199 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
1200 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
1201 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
1202 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1203 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
1204 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
1205 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1206 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
1207 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
1208 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
1209 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
1210 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
1211 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1212 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
1213 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1214 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
1215 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1216 assert_eq!(
1217 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
1218 vec![0, 1, 2, 3, 4]
1219 );
1220 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1221 assert_eq!(
1222 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
1223 vec![0, 1, 2, 3, 4]
1224 );
1225 assert_eq!(
1226 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
1227 vec![0, 1, 2, 3, 4]
1228 );
1229 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1230 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
1231 assert_eq!(
1232 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
1233 vec![0, 1, 2, 3, 4]
1234 );
1235 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
1236 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
1237 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
1238 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1239 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
1240 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
1241 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1242 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
1243 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
1244 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
1245 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1246 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
1247 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1248 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
1249 assert_eq!(
1250 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
1251 vec![0, 1, 2, 3, 4]
1252 );
1253 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1254 assert_eq!(
1255 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
1256 vec![0, 1, 2, 3, 4]
1257 );
1258 assert_eq!(
1259 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
1260 vec![0, 1, 2, 3, 4]
1261 );
1262 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
1263 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
1264 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
1265 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
1266 assert_eq!(
1267 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
1268 vec![0, 1, 2, 3, 4]
1269 );
1270 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1271 assert_eq!(
1272 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
1273 vec![0, 1, 2, 3, 4]
1274 );
1275 assert_eq!(
1276 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
1277 vec![0, 3, 4, 5, 2]
1278 );
1279 assert_eq!(
1280 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
1281 vec![0, 1, 2, 3, 4]
1282 );
1283 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
1284 }
1285
1286 #[test]
1287 fn test_simplify() {
1288 assert_eq!(c(&[0]).simplify(), c(&[0]));
1290 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
1292 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
1293 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
1294 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
1295 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
1296 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
1298 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
1299 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
1300 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
1301 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
1302 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
1303 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
1304 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
1305 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
1306 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
1307 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
1308 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
1309 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
1310 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
1311 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
1312 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
1313 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
1314 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
1315 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
1316 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
1317 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1318 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1319 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1320 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1321 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1322 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1323 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1324 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1325 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1326 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1327 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1328 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1329 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1330 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1331 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1332 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1333 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1334 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1335 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1336 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1337 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1338 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1339 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1340 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1341 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1342 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1343 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1344 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1345 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1346 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1347 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1348 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1349 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1350 }
1351
1352 #[test]
1353 fn test_simplify_by() {
1354 fn enumerate_and_simplify_by(merge: Merge<i32>) -> Merge<(usize, i32)> {
1355 let enumerated = Merge::from_vec(merge.iter().copied().enumerate().collect_vec());
1356 enumerated.simplify_by(|&(_index, value)| value)
1357 }
1358
1359 assert_eq!(enumerate_and_simplify_by(c(&[0])), c(&[(0, 0)]));
1361 assert_eq!(enumerate_and_simplify_by(c(&[1, 0, 0])), c(&[(0, 1)]));
1363 assert_eq!(
1364 enumerate_and_simplify_by(c(&[1, 0, 2])),
1365 c(&[(0, 1), (1, 0), (2, 2)])
1366 );
1367 assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 0])), c(&[(4, 0)]));
1369 assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 1])), c(&[(4, 1)]));
1370 assert_eq!(
1371 enumerate_and_simplify_by(c(&[0, 0, 0, 1, 2])),
1372 c(&[(2, 0), (3, 1), (4, 2)])
1373 );
1374 assert_eq!(
1375 enumerate_and_simplify_by(c(&[0, 1, 2, 2, 0])),
1376 c(&[(0, 0), (1, 1), (4, 0)])
1377 );
1378 assert_eq!(
1379 enumerate_and_simplify_by(c(&[0, 1, 2, 2, 2])),
1380 c(&[(0, 0), (1, 1), (4, 2)])
1381 );
1382 assert_eq!(
1383 enumerate_and_simplify_by(c(&[0, 1, 2, 2, 3])),
1384 c(&[(0, 0), (1, 1), (4, 3)])
1385 );
1386 assert_eq!(
1387 enumerate_and_simplify_by(c(&[0, 1, 2, 3, 4])),
1388 c(&[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])
1389 );
1390 }
1391
1392 #[test]
1393 fn test_update_from_simplified() {
1394 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1396 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1398 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1399 assert_eq!(
1400 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1401 c(&[2, 1, 3])
1402 );
1403 assert_eq!(
1405 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1406 c(&[0, 0, 0, 0, 1])
1407 );
1408 assert_eq!(
1409 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1410 c(&[0, 0, 2, 3, 1])
1411 );
1412 assert_eq!(
1413 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1414 c(&[0, 3, 1, 0, 2])
1415 );
1416 assert_eq!(
1417 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1418 c(&[3, 1, 4, 2, 5])
1419 );
1420
1421 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1422 assert_eq!(
1425 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1426 c(&[0, 0, 10, 1, 11, 2, 4])
1427 );
1428 }
1429
1430 #[test]
1431 fn test_merge_invariants() {
1432 fn check_invariants(terms: &[u32]) {
1433 let merge = Merge::from_vec(terms.to_vec());
1434 assert_eq!(
1436 merge.simplify().simplify(),
1437 merge.simplify(),
1438 "simplify() not idempotent for {merge:?}"
1439 );
1440 assert_eq!(
1442 merge.simplify().resolve_trivial(SameChange::Accept),
1443 merge.resolve_trivial(SameChange::Accept),
1444 "simplify() changed result of resolve_trivial() for {merge:?}"
1445 );
1446 }
1447 check_invariants(&[0]);
1449 for i in 0..=1 {
1450 for j in 0..=i + 1 {
1451 check_invariants(&[i, 0, j]);
1453 for k in 0..=j + 1 {
1454 for l in 0..=k + 1 {
1455 check_invariants(&[0, i, j, k, l]);
1457 }
1458 }
1459 }
1460 }
1461 }
1462
1463 #[test]
1464 fn test_swap_remove() {
1465 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1466 assert_eq!(x.swap_remove(0, 1), (1, 2));
1467 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1468 assert_eq!(x.swap_remove(1, 0), (3, 0));
1469 assert_eq!(x, c(&[4, 5, 6]));
1470 assert_eq!(x.swap_remove(0, 1), (5, 6));
1471 assert_eq!(x, c(&[4]));
1472 }
1473
1474 #[test]
1475 fn test_pad_to() {
1476 let mut x = c(&[1]);
1477 x.pad_to(3, &2);
1478 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1479 x.pad_to(1, &3);
1481 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1482 }
1483
1484 #[test]
1485 fn test_iter() {
1486 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1488 assert_eq!(
1490 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1491 vec![&1, &2, &3, &4, &5]
1492 );
1493 }
1494
1495 #[test]
1496 fn test_from_iter() {
1497 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1499 assert_eq!(
1501 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1502 c(&[1, 2, 3, 4, 5])
1503 );
1504 }
1505
1506 #[test]
1507 #[should_panic]
1508 fn test_from_iter_empty() {
1509 MergeBuilder::from_iter([1; 0]).build();
1510 }
1511
1512 #[test]
1513 #[should_panic]
1514 fn test_from_iter_even() {
1515 MergeBuilder::from_iter([1, 2]).build();
1516 }
1517
1518 #[test]
1519 fn test_extend() {
1520 let mut builder: MergeBuilder<i32> = Default::default();
1522 builder.extend([1]);
1523 assert_eq!(builder.build(), c(&[1]));
1524 let mut builder: MergeBuilder<i32> = Default::default();
1526 builder.extend([1, 2]);
1527 builder.extend([3, 4, 5]);
1528 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1529 }
1530
1531 #[test]
1532 fn test_map() {
1533 fn increment(i: &i32) -> i32 {
1534 i + 1
1535 }
1536 assert_eq!(c(&[1]).map(increment), c(&[2]));
1538 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1540 }
1541
1542 #[test]
1543 fn test_try_map() {
1544 fn sqrt(i: &i32) -> Result<i32, ()> {
1545 if *i >= 0 {
1546 Ok(f64::from(*i).sqrt() as i32)
1547 } else {
1548 Err(())
1549 }
1550 }
1551 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1553 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1554 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1556 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1557 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1558 }
1559
1560 #[test]
1561 fn test_flatten() {
1562 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1564 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1566 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1568 assert_eq!(
1570 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1571 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1572 );
1573 }
1574
1575 #[test]
1576 fn test_zip() {
1577 assert_eq!(c(&[1]).zip(c(&[2])), c(&[(1, 2)]));
1579 assert_eq!(
1581 c(&[1, 2, 3]).zip(c(&[4, 5, 6])),
1582 c(&[(1, 4), (2, 5), (3, 6)])
1583 );
1584 }
1585
1586 #[test]
1587 fn test_unzip() {
1588 assert_eq!(c(&[(1, 2)]).unzip(), (c(&[1]), c(&[2])));
1590 assert_eq!(
1592 c(&[(1, 4), (2, 5), (3, 6)]).unzip(),
1593 (c(&[1, 2, 3]), c(&[4, 5, 6]))
1594 );
1595 }
1596}