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;
35use crate::backend::BackendResult;
36use crate::backend::CopyId;
37use crate::backend::FileId;
38use crate::backend::TreeValue;
39use crate::content_hash::ContentHash;
40use crate::content_hash::DigestUpdate;
41use crate::repo_path::RepoPath;
42use crate::store::Store;
43use crate::tree::Tree;
44
45pub fn trivial_merge<T>(values: &[T]) -> Option<&T>
48where
49 T: Eq + Hash,
50{
51 assert!(
52 values.len() % 2 == 1,
53 "trivial_merge() requires an odd number of terms"
54 );
55 if let [add] = values {
57 return Some(add);
58 } else if let [add0, remove, add1] = values {
59 return if add0 == add1 {
60 Some(add0)
61 } else if add0 == remove {
62 Some(add1)
63 } else if add1 == remove {
64 Some(add0)
65 } else {
66 None
67 };
68 }
69
70 let mut counts: HashMap<&T, i32> = HashMap::new();
74 for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
75 counts.entry(value).and_modify(|e| *e += n).or_insert(n);
76 }
77
78 counts.retain(|_, count| *count != 0);
81 if counts.len() == 1 {
82 let (value, count) = counts.into_iter().next().unwrap();
84 assert_eq!(count, 1);
85 Some(value)
86 } else if counts.len() == 2 {
87 let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
95 assert_eq!(count1 + count2, 1);
96 if count1 > 0 {
97 Some(value1)
98 } else {
99 Some(value2)
100 }
101 } else {
102 None
103 }
104}
105
106#[derive(PartialEq, Eq, Hash, Clone, serde::Serialize)]
112#[serde(transparent)]
113pub struct Merge<T> {
114 values: SmallVec<[T; 1]>,
116}
117
118impl<T: Debug> Debug for Merge<T> {
119 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
120 if let Some(value) = self.as_resolved() {
123 f.debug_tuple("Resolved").field(value).finish()
124 } else {
125 f.debug_tuple("Conflicted").field(&self.values).finish()
126 }
127 }
128}
129
130impl<T> Merge<T> {
131 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
134 let values = values.into();
135 assert!(values.len() % 2 != 0, "must have an odd number of terms");
136 Self { values }
137 }
138
139 pub fn from_removes_adds(
141 removes: impl IntoIterator<Item = T>,
142 adds: impl IntoIterator<Item = T>,
143 ) -> Self {
144 let removes = removes.into_iter();
145 let mut adds = adds.into_iter();
146 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
147 values.push(adds.next().expect("must have at least one add"));
148 for diff in removes.zip_longest(adds) {
149 let (remove, add) = diff.both().expect("must have one more adds than removes");
150 values.extend([remove, add]);
151 }
152 Self { values }
153 }
154
155 pub const fn resolved(value: T) -> Self {
157 Self {
158 values: smallvec_inline![value],
159 }
160 }
161
162 pub fn from_legacy_form(
165 removes: impl IntoIterator<Item = T>,
166 adds: impl IntoIterator<Item = T>,
167 ) -> Merge<Option<T>> {
168 let removes = removes.into_iter();
169 let mut adds = adds.into_iter().fuse();
170 let mut values = smallvec_inline![adds.next()];
171 for diff in removes.zip_longest(adds) {
172 let (remove, add) = diff.map_any(Some, Some).or_default();
173 values.extend([remove, add]);
174 }
175 Merge { values }
176 }
177
178 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
180 self.values[1..].iter().step_by(2)
181 }
182
183 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
185 self.values.iter().step_by(2)
186 }
187
188 pub fn first(&self) -> &T {
190 &self.values[0]
191 }
192
193 pub fn get_remove(&self, index: usize) -> Option<&T> {
196 self.values.get(index * 2 + 1)
197 }
198
199 pub fn get_add(&self, index: usize) -> Option<&T> {
203 self.values.get(index * 2)
204 }
205
206 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
209 let add = self.values.swap_remove(add_index * 2);
211 let remove = self.values.swap_remove(remove_index * 2 + 1);
212 (remove, add)
213 }
214
215 pub fn num_sides(&self) -> usize {
217 self.values.len() / 2 + 1
218 }
219
220 pub fn is_resolved(&self) -> bool {
222 self.values.len() == 1
223 }
224
225 pub fn as_resolved(&self) -> Option<&T> {
228 if let [value] = &self.values[..] {
229 Some(value)
230 } else {
231 None
232 }
233 }
234
235 pub fn into_resolved(mut self) -> Result<T, Self> {
238 if self.values.len() == 1 {
239 Ok(self.values.pop().unwrap())
240 } else {
241 Err(self)
242 }
243 }
244
245 fn get_simplified_mapping(&self) -> Vec<usize>
251 where
252 T: PartialEq,
253 {
254 let unsimplified_len = self.values.len();
255 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
256
257 let mut add_index = 0;
258 while add_index < simplified_to_original_indices.len() {
259 let add = &self.values[simplified_to_original_indices[add_index]];
260 let mut remove_indices = simplified_to_original_indices
261 .iter()
262 .enumerate()
263 .skip(1)
264 .step_by(2);
265 if let Some((remove_index, _)) = remove_indices
266 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
267 {
268 simplified_to_original_indices.swap(remove_index + 1, add_index);
271 simplified_to_original_indices.drain(remove_index..remove_index + 2);
272 } else {
273 add_index += 2;
274 }
275 }
276
277 simplified_to_original_indices
278 }
279
280 #[must_use]
283 pub fn simplify(&self) -> Self
284 where
285 T: PartialEq + Clone,
286 {
287 let mapping = self.get_simplified_mapping();
288 let values = mapping
290 .iter()
291 .map(|index| self.values[*index].clone())
292 .collect();
293 Self { values }
294 }
295
296 pub fn update_from_simplified(mut self, simplified: Self) -> Self
298 where
299 T: PartialEq,
300 {
301 let mapping = self.get_simplified_mapping();
302 assert_eq!(mapping.len(), simplified.values.len());
303 for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
304 self.values[index] = value;
305 }
306 self
307 }
308
309 pub fn resolve_trivial(&self) -> Option<&T>
312 where
313 T: Eq + Hash,
314 {
315 trivial_merge(&self.values)
316 }
317
318 pub fn pad_to(&mut self, num_sides: usize, value: &T)
321 where
322 T: Clone,
323 {
324 if num_sides <= self.num_sides() {
325 return;
326 }
327 self.values.resize(num_sides * 2 - 1, value.clone());
328 }
329
330 pub fn as_slice(&self) -> &[T] {
334 &self.values
335 }
336
337 pub fn iter(&self) -> slice::Iter<'_, T> {
341 self.values.iter()
342 }
343
344 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
346 self.values.iter_mut()
347 }
348
349 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
351 let values = self.values.iter().map(f).collect();
352 Merge { values }
353 }
354
355 pub fn try_map<'a, U, E>(
358 &'a self,
359 f: impl FnMut(&'a T) -> Result<U, E>,
360 ) -> Result<Merge<U>, E> {
361 let values = self.values.iter().map(f).try_collect()?;
362 Ok(Merge { values })
363 }
364
365 pub async fn try_map_async<'a, F, U, E>(
369 &'a self,
370 f: impl FnMut(&'a T) -> F,
371 ) -> Result<Merge<U>, E>
372 where
373 F: Future<Output = Result<U, E>>,
374 {
375 let values = try_join_all(self.values.iter().map(f)).await?;
376 Ok(Merge {
377 values: values.into(),
378 })
379 }
380}
381
382#[derive(Clone, Debug, PartialEq, Eq)]
391pub struct MergeBuilder<T> {
392 values: SmallVec<[T; 1]>,
393}
394
395impl<T> Default for MergeBuilder<T> {
396 fn default() -> Self {
397 Self {
398 values: Default::default(),
399 }
400 }
401}
402
403impl<T> MergeBuilder<T> {
404 pub fn build(self) -> Merge<T> {
407 Merge::from_vec(self.values)
408 }
409}
410
411impl<T> IntoIterator for Merge<T> {
412 type Item = T;
413 type IntoIter = smallvec::IntoIter<[T; 1]>;
414
415 fn into_iter(self) -> Self::IntoIter {
416 self.values.into_iter()
417 }
418}
419
420impl<T> FromIterator<T> for MergeBuilder<T> {
421 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
422 let mut builder = Self::default();
423 builder.extend(iter);
424 builder
425 }
426}
427
428impl<T> Extend<T> for MergeBuilder<T> {
429 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
430 self.values.extend(iter);
431 }
432}
433
434impl<T> Merge<Option<T>> {
435 pub fn absent() -> Self {
437 Self::resolved(None)
438 }
439
440 pub fn normal(value: T) -> Self {
442 Self::resolved(Some(value))
443 }
444
445 pub fn is_absent(&self) -> bool {
447 matches!(self.as_resolved(), Some(None))
448 }
449
450 pub fn is_present(&self) -> bool {
452 !self.is_absent()
453 }
454
455 pub fn as_normal(&self) -> Option<&T> {
457 self.as_resolved()?.as_ref()
458 }
459
460 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
464 let mut removes = Vec::with_capacity(self.values.len() / 2);
466 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
467 let mut values = self.values.into_iter();
468 adds.extend(values.next().unwrap());
469 while let Some(remove) = values.next() {
470 removes.extend(remove);
471 adds.extend(values.next().unwrap());
472 }
473 (removes, adds)
474 }
475}
476
477impl<T: Clone> Merge<Option<&T>> {
478 pub fn cloned(&self) -> Merge<Option<T>> {
480 self.map(|value| value.cloned())
481 }
482}
483
484impl<T> Merge<Merge<T>> {
485 pub fn flatten(self) -> Merge<T> {
503 let mut outer_values = self.values.into_iter();
504 let mut result = outer_values.next().unwrap();
505 while let Some(mut remove) = outer_values.next() {
506 remove.values.rotate_left(1);
509 for i in 0..remove.values.len() / 2 {
510 remove.values.swap(i * 2, i * 2 + 1);
511 }
512 result.values.extend(remove.values);
513 let add = outer_values.next().unwrap();
514 result.values.extend(add.values);
515 }
516 result
517 }
518}
519
520impl<T: ContentHash> ContentHash for Merge<T> {
521 fn hash(&self, state: &mut impl DigestUpdate) {
522 self.values.hash(state);
523 }
524}
525
526pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
528
529pub type MergedTreeValue = Merge<Option<TreeValue>>;
536
537impl MergedTreeValue {
538 pub fn from_backend_conflict(conflict: backend::Conflict) -> Self {
541 let removes = conflict.removes.into_iter().map(|term| term.value);
542 let adds = conflict.adds.into_iter().map(|term| term.value);
543 Merge::from_legacy_form(removes, adds)
544 }
545
546 pub fn into_backend_conflict(self) -> backend::Conflict {
550 let (removes, adds) = self.into_legacy_form();
551 let removes = removes
552 .into_iter()
553 .map(|value| backend::ConflictTerm { value })
554 .collect();
555 let adds = adds
556 .into_iter()
557 .map(|value| backend::ConflictTerm { value })
558 .collect();
559 backend::Conflict { removes, adds }
560 }
561}
562
563impl<T> Merge<Option<T>>
564where
565 T: Borrow<TreeValue>,
566{
567 pub fn is_tree(&self) -> bool {
569 self.is_present()
570 && self.iter().all(|value| {
571 matches!(
572 borrow_tree_value(value.as_ref()),
573 Some(TreeValue::Tree(_)) | None
574 )
575 })
576 }
577
578 pub fn is_file_like(&self) -> bool {
580 self.is_present() && !self.is_tree()
581 }
582
583 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
588 let file_ids = self
589 .try_map(|term| match borrow_tree_value(term.as_ref()) {
590 None => Ok(None),
591 Some(TreeValue::File {
592 id,
593 executable: _,
594 copy_id: _,
595 }) => Ok(Some(id.clone())),
596 _ => Err(()),
597 })
598 .ok()?;
599
600 Some(file_ids)
601 }
602
603 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
606 self.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(*executable)),
613 _ => Err(()),
614 })
615 .ok()
616 }
617
618 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
621 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
622 None => Ok(None),
623 Some(TreeValue::File {
624 id: _,
625 executable: _,
626 copy_id,
627 }) => Ok(Some(copy_id.clone())),
628 _ => Err(()),
629 })
630 .ok()
631 }
632
633 pub async fn to_tree_merge(
638 &self,
639 store: &Arc<Store>,
640 dir: &RepoPath,
641 ) -> BackendResult<Option<Merge<Tree>>> {
642 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
643 None => Ok(None),
644 Some(TreeValue::Tree(id)) => Ok(Some(id)),
645 Some(_) => Err(()),
646 });
647 if let Ok(tree_id_merge) = tree_id_merge {
648 Ok(Some(
649 tree_id_merge
650 .try_map_async(async |id| {
651 if let Some(id) = id {
652 store.get_tree_async(dir.to_owned(), id).await
653 } else {
654 Ok(Tree::empty(store.clone(), dir.to_owned()))
655 }
656 })
657 .await?,
658 ))
659 } else {
660 Ok(None)
661 }
662 }
663
664 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
670 assert_eq!(self.values.len(), file_ids.values.len());
671 let values = zip(self.iter(), file_ids.iter().cloned())
672 .map(
673 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
674 (
675 Some(TreeValue::File {
676 id: _,
677 executable,
678 copy_id,
679 }),
680 Some(id),
681 ) => Some(TreeValue::File {
682 id,
683 executable: *executable,
684 copy_id: copy_id.clone(),
685 }),
686 (None, None) => None,
687 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
688 },
689 )
690 .collect();
691 Merge { values }
692 }
693
694 pub fn describe(&self) -> String {
696 let mut buf = String::new();
697 writeln!(buf, "Conflict:").unwrap();
698 for term in self.removes().flatten() {
699 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
700 }
701 for term in self.adds().flatten() {
702 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
703 }
704 buf
705 }
706}
707
708fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
709 term.map(|value| value.borrow())
710}
711
712fn describe_conflict_term(value: &TreeValue) -> String {
713 match value {
714 TreeValue::File {
715 id,
716 executable: false,
717 copy_id: _,
718 } => {
719 format!("file with id {id}")
721 }
722 TreeValue::File {
723 id,
724 executable: true,
725 copy_id: _,
726 } => {
727 format!("executable file with id {id}")
729 }
730 TreeValue::Symlink(id) => {
731 format!("symlink with id {id}")
732 }
733 TreeValue::Tree(id) => {
734 format!("tree with id {id}")
735 }
736 TreeValue::GitSubmodule(id) => {
737 format!("Git submodule with id {id}")
738 }
739 TreeValue::Conflict(id) => {
740 format!("Conflict with id {id}")
741 }
742 }
743}
744
745#[cfg(test)]
746mod tests {
747 use super::*;
748
749 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
750 Merge::from_vec(terms.to_vec())
751 }
752
753 #[test]
754 fn test_trivial_merge() {
755 assert_eq!(trivial_merge(&[0]), Some(&0));
756 assert_eq!(trivial_merge(&[0, 0, 0]), Some(&0));
757 assert_eq!(trivial_merge(&[0, 0, 1]), Some(&1));
758 assert_eq!(trivial_merge(&[0, 1, 0]), Some(&0));
759 assert_eq!(trivial_merge(&[0, 1, 1]), Some(&0));
760 assert_eq!(trivial_merge(&[0, 1, 2]), None);
761 assert_eq!(trivial_merge(&[0, 0, 0, 0, 0]), Some(&0));
762 assert_eq!(trivial_merge(&[0, 0, 0, 0, 1]), Some(&1));
763 assert_eq!(trivial_merge(&[0, 0, 0, 1, 0]), Some(&0));
764 assert_eq!(trivial_merge(&[0, 0, 0, 1, 1]), Some(&0));
765 assert_eq!(trivial_merge(&[0, 0, 0, 1, 2]), None);
766 assert_eq!(trivial_merge(&[0, 0, 1, 0, 0]), Some(&1));
767 assert_eq!(trivial_merge(&[0, 0, 1, 0, 1]), Some(&1));
768 assert_eq!(trivial_merge(&[0, 0, 1, 0, 2]), None);
769 assert_eq!(trivial_merge(&[0, 0, 1, 1, 0]), Some(&0));
770 assert_eq!(trivial_merge(&[0, 0, 1, 1, 1]), Some(&1));
771 assert_eq!(trivial_merge(&[0, 0, 1, 1, 2]), Some(&2));
772 assert_eq!(trivial_merge(&[0, 0, 1, 2, 0]), None);
773 assert_eq!(trivial_merge(&[0, 0, 1, 2, 1]), Some(&1));
774 assert_eq!(trivial_merge(&[0, 0, 1, 2, 2]), Some(&1));
775 assert_eq!(trivial_merge(&[0, 0, 1, 2, 3]), None);
776 assert_eq!(trivial_merge(&[0, 1, 0, 0, 0]), Some(&0));
777 assert_eq!(trivial_merge(&[0, 1, 0, 0, 1]), Some(&0));
778 assert_eq!(trivial_merge(&[0, 1, 0, 0, 2]), None);
779 assert_eq!(trivial_merge(&[0, 1, 0, 1, 0]), Some(&0));
780 assert_eq!(trivial_merge(&[0, 1, 0, 1, 1]), Some(&0));
781 assert_eq!(trivial_merge(&[0, 1, 0, 1, 2]), None);
782 assert_eq!(trivial_merge(&[0, 1, 0, 2, 0]), None);
783 assert_eq!(trivial_merge(&[0, 1, 0, 2, 1]), Some(&0));
784 assert_eq!(trivial_merge(&[0, 1, 0, 2, 2]), Some(&0));
785 assert_eq!(trivial_merge(&[0, 1, 0, 2, 3]), None);
786 assert_eq!(trivial_merge(&[0, 1, 1, 0, 0]), Some(&0));
787 assert_eq!(trivial_merge(&[0, 1, 1, 0, 1]), Some(&1));
788 assert_eq!(trivial_merge(&[0, 1, 1, 0, 2]), Some(&2));
789 assert_eq!(trivial_merge(&[0, 1, 1, 1, 0]), Some(&0));
790 assert_eq!(trivial_merge(&[0, 1, 1, 1, 1]), Some(&0));
791 assert_eq!(trivial_merge(&[0, 1, 1, 1, 2]), None);
792 assert_eq!(trivial_merge(&[0, 1, 1, 2, 0]), Some(&0));
793 assert_eq!(trivial_merge(&[0, 1, 1, 2, 1]), None);
794 assert_eq!(trivial_merge(&[0, 1, 1, 2, 2]), Some(&0));
795 assert_eq!(trivial_merge(&[0, 1, 1, 2, 3]), None);
796 assert_eq!(trivial_merge(&[0, 1, 2, 0, 0]), None);
797 assert_eq!(trivial_merge(&[0, 1, 2, 0, 1]), Some(&2));
798 assert_eq!(trivial_merge(&[0, 1, 2, 0, 2]), Some(&2));
799 assert_eq!(trivial_merge(&[0, 1, 2, 0, 3]), None);
800 assert_eq!(trivial_merge(&[0, 1, 2, 1, 0]), None);
801 assert_eq!(trivial_merge(&[0, 1, 2, 1, 1]), None);
802 assert_eq!(trivial_merge(&[0, 1, 2, 1, 2]), None);
803 assert_eq!(trivial_merge(&[0, 1, 2, 1, 3]), None);
804 assert_eq!(trivial_merge(&[0, 1, 2, 2, 0]), Some(&0));
805 assert_eq!(trivial_merge(&[0, 1, 2, 2, 1]), Some(&0));
806 assert_eq!(trivial_merge(&[0, 1, 2, 2, 2]), None);
807 assert_eq!(trivial_merge(&[0, 1, 2, 2, 3]), None);
808 assert_eq!(trivial_merge(&[0, 1, 2, 3, 0]), None);
809 assert_eq!(trivial_merge(&[0, 1, 2, 3, 1]), None);
810 assert_eq!(trivial_merge(&[0, 1, 2, 3, 2]), None);
811 assert_eq!(trivial_merge(&[0, 1, 2, 3, 3]), None);
812 assert_eq!(trivial_merge(&[0, 1, 2, 3, 4]), None);
813 }
814
815 #[test]
816 fn test_legacy_form_conversion() {
817 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
818 where
819 T: Clone + PartialEq + std::fmt::Debug,
820 {
821 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
822 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
823 }
824 test_equivalent(
826 (vec![], vec![0]),
827 Merge::from_removes_adds(vec![], vec![Some(0)]),
828 );
829 test_equivalent(
831 (vec![0], vec![1, 2]),
832 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
833 );
834 test_equivalent(
836 (vec![0], vec![1]),
837 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
838 );
839 test_equivalent(
841 (vec![], vec![0, 1]),
842 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
843 );
844 test_equivalent(
846 (vec![0, 1], vec![2, 3, 4]),
847 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
848 );
849 test_equivalent(
851 (vec![0, 1], vec![]),
852 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
853 );
854 }
855
856 #[test]
857 fn test_as_resolved() {
858 assert_eq!(
859 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
860 Some(&0)
861 );
862 assert_eq!(
864 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
865 None
866 );
867 }
868
869 #[test]
870 fn test_get_simplified_mapping() {
871 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
873 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
875 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
876 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
877 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
878 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
879 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
881 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
882 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
883 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
884 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
885 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
886 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
887 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
888 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
889 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
890 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
891 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
892 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
893 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
894 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
895 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
896 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
897 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
898 assert_eq!(
899 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
900 vec![0, 1, 2, 3, 4]
901 );
902 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
903 assert_eq!(
904 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
905 vec![0, 1, 2, 3, 4]
906 );
907 assert_eq!(
908 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
909 vec![0, 1, 2, 3, 4]
910 );
911 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
912 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
913 assert_eq!(
914 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
915 vec![0, 1, 2, 3, 4]
916 );
917 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
918 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
919 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
920 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
921 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
922 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
923 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
924 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
925 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
926 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
927 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
928 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
929 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
930 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
931 assert_eq!(
932 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
933 vec![0, 1, 2, 3, 4]
934 );
935 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
936 assert_eq!(
937 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
938 vec![0, 1, 2, 3, 4]
939 );
940 assert_eq!(
941 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
942 vec![0, 1, 2, 3, 4]
943 );
944 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
945 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
946 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
947 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
948 assert_eq!(
949 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
950 vec![0, 1, 2, 3, 4]
951 );
952 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
953 assert_eq!(
954 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
955 vec![0, 1, 2, 3, 4]
956 );
957 assert_eq!(
958 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
959 vec![0, 3, 4, 5, 2]
960 );
961 assert_eq!(
962 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
963 vec![0, 1, 2, 3, 4]
964 );
965 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
966 }
967
968 #[test]
969 fn test_simplify() {
970 assert_eq!(c(&[0]).simplify(), c(&[0]));
972 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
974 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
975 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
976 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
977 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
978 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
980 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
981 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
982 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
983 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
984 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
985 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
986 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
987 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
988 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
989 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
990 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
991 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
992 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
993 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
994 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
995 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
996 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
997 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
998 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
999 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1000 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1001 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1002 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1003 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1004 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1005 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1006 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1007 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1008 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1009 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1010 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1011 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1012 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1013 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1014 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1015 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1016 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1017 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1018 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1019 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1020 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1021 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1022 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1023 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1024 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1025 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1026 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1027 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1028 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1029 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1030 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1031 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1032 }
1033
1034 #[test]
1035 fn test_update_from_simplified() {
1036 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1038 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1040 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1041 assert_eq!(
1042 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1043 c(&[2, 1, 3])
1044 );
1045 assert_eq!(
1047 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1048 c(&[0, 0, 0, 0, 1])
1049 );
1050 assert_eq!(
1051 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1052 c(&[0, 0, 2, 3, 1])
1053 );
1054 assert_eq!(
1055 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1056 c(&[0, 3, 1, 0, 2])
1057 );
1058 assert_eq!(
1059 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1060 c(&[3, 1, 4, 2, 5])
1061 );
1062
1063 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1064 assert_eq!(
1067 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1068 c(&[0, 0, 10, 1, 11, 2, 4])
1069 );
1070 }
1071
1072 #[test]
1073 fn test_merge_invariants() {
1074 fn check_invariants(terms: &[u32]) {
1075 let merge = Merge::from_vec(terms.to_vec());
1076 assert_eq!(
1078 merge.simplify().simplify(),
1079 merge.simplify(),
1080 "simplify() not idempotent for {merge:?}"
1081 );
1082 assert_eq!(
1084 merge.simplify().resolve_trivial(),
1085 merge.resolve_trivial(),
1086 "simplify() changed result of resolve_trivial() for {merge:?}"
1087 );
1088 }
1089 check_invariants(&[0]);
1091 for i in 0..=1 {
1092 for j in 0..=i + 1 {
1093 check_invariants(&[i, 0, j]);
1095 for k in 0..=j + 1 {
1096 for l in 0..=k + 1 {
1097 check_invariants(&[0, i, j, k, l]);
1099 }
1100 }
1101 }
1102 }
1103 }
1104
1105 #[test]
1106 fn test_swap_remove() {
1107 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1108 assert_eq!(x.swap_remove(0, 1), (1, 2));
1109 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1110 assert_eq!(x.swap_remove(1, 0), (3, 0));
1111 assert_eq!(x, c(&[4, 5, 6]));
1112 assert_eq!(x.swap_remove(0, 1), (5, 6));
1113 assert_eq!(x, c(&[4]));
1114 }
1115
1116 #[test]
1117 fn test_pad_to() {
1118 let mut x = c(&[1]);
1119 x.pad_to(3, &2);
1120 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1121 x.pad_to(1, &3);
1123 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1124 }
1125
1126 #[test]
1127 fn test_iter() {
1128 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1130 assert_eq!(
1132 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1133 vec![&1, &2, &3, &4, &5]
1134 );
1135 }
1136
1137 #[test]
1138 fn test_from_iter() {
1139 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1141 assert_eq!(
1143 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1144 c(&[1, 2, 3, 4, 5])
1145 );
1146 }
1147
1148 #[test]
1149 #[should_panic]
1150 fn test_from_iter_empty() {
1151 MergeBuilder::from_iter([1; 0]).build();
1152 }
1153
1154 #[test]
1155 #[should_panic]
1156 fn test_from_iter_even() {
1157 MergeBuilder::from_iter([1, 2]).build();
1158 }
1159
1160 #[test]
1161 fn test_extend() {
1162 let mut builder: MergeBuilder<i32> = Default::default();
1164 builder.extend([1]);
1165 assert_eq!(builder.build(), c(&[1]));
1166 let mut builder: MergeBuilder<i32> = Default::default();
1168 builder.extend([1, 2]);
1169 builder.extend([3, 4, 5]);
1170 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1171 }
1172
1173 #[test]
1174 fn test_map() {
1175 fn increment(i: &i32) -> i32 {
1176 i + 1
1177 }
1178 assert_eq!(c(&[1]).map(increment), c(&[2]));
1180 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1182 }
1183
1184 #[test]
1185 fn test_try_map() {
1186 fn sqrt(i: &i32) -> Result<i32, ()> {
1187 if *i >= 0 {
1188 Ok((*i as f64).sqrt() as i32)
1189 } else {
1190 Err(())
1191 }
1192 }
1193 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1195 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1196 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1198 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1199 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1200 }
1201
1202 #[test]
1203 fn test_flatten() {
1204 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1206 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1208 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1210 assert_eq!(
1212 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1213 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1214 );
1215 }
1216}