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_inline;
32use smallvec::SmallVec;
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 Merge { 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 Merge { values }
153 }
154
155 pub const fn resolved(value: T) -> Self {
157 Merge {
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, Merge<T>> {
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 Merge { values }
294 }
295
296 pub fn update_from_simplified(mut self, simplified: Merge<T>) -> 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 = MergeBuilder::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> {
499 let mut outer_values = self.values.into_iter();
500 let mut result = outer_values.next().unwrap();
501 while let Some(mut remove) = outer_values.next() {
502 remove.values.rotate_left(1);
505 for i in 0..remove.values.len() / 2 {
506 remove.values.swap(i * 2, i * 2 + 1);
507 }
508 result.values.extend(remove.values);
509 let add = outer_values.next().unwrap();
510 result.values.extend(add.values);
511 }
512 result
513 }
514}
515
516impl<T: ContentHash> ContentHash for Merge<T> {
517 fn hash(&self, state: &mut impl DigestUpdate) {
518 self.values.hash(state);
519 }
520}
521
522pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
524
525pub type MergedTreeValue = Merge<Option<TreeValue>>;
532
533impl MergedTreeValue {
534 pub fn from_backend_conflict(conflict: backend::Conflict) -> Self {
537 let removes = conflict.removes.into_iter().map(|term| term.value);
538 let adds = conflict.adds.into_iter().map(|term| term.value);
539 Merge::from_legacy_form(removes, adds)
540 }
541
542 pub fn into_backend_conflict(self) -> backend::Conflict {
546 let (removes, adds) = self.into_legacy_form();
547 let removes = removes
548 .into_iter()
549 .map(|value| backend::ConflictTerm { value })
550 .collect();
551 let adds = adds
552 .into_iter()
553 .map(|value| backend::ConflictTerm { value })
554 .collect();
555 backend::Conflict { removes, adds }
556 }
557}
558
559impl<T> Merge<Option<T>>
560where
561 T: Borrow<TreeValue>,
562{
563 pub fn is_tree(&self) -> bool {
565 self.is_present()
566 && self.iter().all(|value| {
567 matches!(
568 borrow_tree_value(value.as_ref()),
569 Some(TreeValue::Tree(_)) | None
570 )
571 })
572 }
573
574 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
579 let file_ids = self
580 .try_map(|term| match borrow_tree_value(term.as_ref()) {
581 None => Ok(None),
582 Some(TreeValue::File {
583 id,
584 executable: _,
585 copy_id: _,
586 }) => Ok(Some(id.clone())),
587 _ => Err(()),
588 })
589 .ok()?;
590
591 Some(file_ids)
592 }
593
594 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
597 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
598 None => Ok(None),
599 Some(TreeValue::File {
600 id: _,
601 executable,
602 copy_id: _,
603 }) => Ok(Some(*executable)),
604 _ => Err(()),
605 })
606 .ok()
607 }
608
609 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
612 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
613 None => Ok(None),
614 Some(TreeValue::File {
615 id: _,
616 executable: _,
617 copy_id,
618 }) => Ok(Some(copy_id.clone())),
619 _ => Err(()),
620 })
621 .ok()
622 }
623
624 pub async fn to_tree_merge(
629 &self,
630 store: &Arc<Store>,
631 dir: &RepoPath,
632 ) -> BackendResult<Option<Merge<Tree>>> {
633 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
634 None => Ok(None),
635 Some(TreeValue::Tree(id)) => Ok(Some(id)),
636 Some(_) => Err(()),
637 });
638 if let Ok(tree_id_merge) = tree_id_merge {
639 Ok(Some(
640 tree_id_merge
641 .try_map_async(|id| async move {
642 if let Some(id) = id {
643 store.get_tree_async(dir.to_owned(), id).await
644 } else {
645 Ok(Tree::empty(store.clone(), dir.to_owned()))
646 }
647 })
648 .await?,
649 ))
650 } else {
651 Ok(None)
652 }
653 }
654
655 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
661 assert_eq!(self.values.len(), file_ids.values.len());
662 let values = zip(self.iter(), file_ids.iter().cloned())
663 .map(
664 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
665 (
666 Some(TreeValue::File {
667 id: _,
668 executable,
669 copy_id,
670 }),
671 Some(id),
672 ) => Some(TreeValue::File {
673 id,
674 executable: *executable,
675 copy_id: copy_id.clone(),
676 }),
677 (None, None) => None,
678 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
679 },
680 )
681 .collect();
682 Merge { values }
683 }
684
685 pub fn describe(&self) -> String {
687 let mut buf = String::new();
688 writeln!(buf, "Conflict:").unwrap();
689 for term in self.removes().flatten() {
690 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
691 }
692 for term in self.adds().flatten() {
693 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
694 }
695 buf
696 }
697}
698
699fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
700 term.map(|value| value.borrow())
701}
702
703fn describe_conflict_term(value: &TreeValue) -> String {
704 match value {
705 TreeValue::File {
706 id,
707 executable: false,
708 copy_id: _,
709 } => {
710 format!("file with id {id}")
712 }
713 TreeValue::File {
714 id,
715 executable: true,
716 copy_id: _,
717 } => {
718 format!("executable file with id {id}")
720 }
721 TreeValue::Symlink(id) => {
722 format!("symlink with id {id}")
723 }
724 TreeValue::Tree(id) => {
725 format!("tree with id {id}")
726 }
727 TreeValue::GitSubmodule(id) => {
728 format!("Git submodule with id {id}")
729 }
730 TreeValue::Conflict(id) => {
731 format!("Conflict with id {id}")
732 }
733 }
734}
735
736#[cfg(test)]
737mod tests {
738 use super::*;
739
740 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
741 Merge::from_vec(terms.to_vec())
742 }
743
744 #[test]
745 fn test_trivial_merge() {
746 assert_eq!(trivial_merge(&[0]), Some(&0));
747 assert_eq!(trivial_merge(&[0, 0, 0]), Some(&0));
748 assert_eq!(trivial_merge(&[0, 0, 1]), Some(&1));
749 assert_eq!(trivial_merge(&[0, 1, 0]), Some(&0));
750 assert_eq!(trivial_merge(&[0, 1, 1]), Some(&0));
751 assert_eq!(trivial_merge(&[0, 1, 2]), None);
752 assert_eq!(trivial_merge(&[0, 0, 0, 0, 0]), Some(&0));
753 assert_eq!(trivial_merge(&[0, 0, 0, 0, 1]), Some(&1));
754 assert_eq!(trivial_merge(&[0, 0, 0, 1, 0]), Some(&0));
755 assert_eq!(trivial_merge(&[0, 0, 0, 1, 1]), Some(&0));
756 assert_eq!(trivial_merge(&[0, 0, 0, 1, 2]), None);
757 assert_eq!(trivial_merge(&[0, 0, 1, 0, 0]), Some(&1));
758 assert_eq!(trivial_merge(&[0, 0, 1, 0, 1]), Some(&1));
759 assert_eq!(trivial_merge(&[0, 0, 1, 0, 2]), None);
760 assert_eq!(trivial_merge(&[0, 0, 1, 1, 0]), Some(&0));
761 assert_eq!(trivial_merge(&[0, 0, 1, 1, 1]), Some(&1));
762 assert_eq!(trivial_merge(&[0, 0, 1, 1, 2]), Some(&2));
763 assert_eq!(trivial_merge(&[0, 0, 1, 2, 0]), None);
764 assert_eq!(trivial_merge(&[0, 0, 1, 2, 1]), Some(&1));
765 assert_eq!(trivial_merge(&[0, 0, 1, 2, 2]), Some(&1));
766 assert_eq!(trivial_merge(&[0, 0, 1, 2, 3]), None);
767 assert_eq!(trivial_merge(&[0, 1, 0, 0, 0]), Some(&0));
768 assert_eq!(trivial_merge(&[0, 1, 0, 0, 1]), Some(&0));
769 assert_eq!(trivial_merge(&[0, 1, 0, 0, 2]), None);
770 assert_eq!(trivial_merge(&[0, 1, 0, 1, 0]), Some(&0));
771 assert_eq!(trivial_merge(&[0, 1, 0, 1, 1]), Some(&0));
772 assert_eq!(trivial_merge(&[0, 1, 0, 1, 2]), None);
773 assert_eq!(trivial_merge(&[0, 1, 0, 2, 0]), None);
774 assert_eq!(trivial_merge(&[0, 1, 0, 2, 1]), Some(&0));
775 assert_eq!(trivial_merge(&[0, 1, 0, 2, 2]), Some(&0));
776 assert_eq!(trivial_merge(&[0, 1, 0, 2, 3]), None);
777 assert_eq!(trivial_merge(&[0, 1, 1, 0, 0]), Some(&0));
778 assert_eq!(trivial_merge(&[0, 1, 1, 0, 1]), Some(&1));
779 assert_eq!(trivial_merge(&[0, 1, 1, 0, 2]), Some(&2));
780 assert_eq!(trivial_merge(&[0, 1, 1, 1, 0]), Some(&0));
781 assert_eq!(trivial_merge(&[0, 1, 1, 1, 1]), Some(&0));
782 assert_eq!(trivial_merge(&[0, 1, 1, 1, 2]), None);
783 assert_eq!(trivial_merge(&[0, 1, 1, 2, 0]), Some(&0));
784 assert_eq!(trivial_merge(&[0, 1, 1, 2, 1]), None);
785 assert_eq!(trivial_merge(&[0, 1, 1, 2, 2]), Some(&0));
786 assert_eq!(trivial_merge(&[0, 1, 1, 2, 3]), None);
787 assert_eq!(trivial_merge(&[0, 1, 2, 0, 0]), None);
788 assert_eq!(trivial_merge(&[0, 1, 2, 0, 1]), Some(&2));
789 assert_eq!(trivial_merge(&[0, 1, 2, 0, 2]), Some(&2));
790 assert_eq!(trivial_merge(&[0, 1, 2, 0, 3]), None);
791 assert_eq!(trivial_merge(&[0, 1, 2, 1, 0]), None);
792 assert_eq!(trivial_merge(&[0, 1, 2, 1, 1]), None);
793 assert_eq!(trivial_merge(&[0, 1, 2, 1, 2]), None);
794 assert_eq!(trivial_merge(&[0, 1, 2, 1, 3]), None);
795 assert_eq!(trivial_merge(&[0, 1, 2, 2, 0]), Some(&0));
796 assert_eq!(trivial_merge(&[0, 1, 2, 2, 1]), Some(&0));
797 assert_eq!(trivial_merge(&[0, 1, 2, 2, 2]), None);
798 assert_eq!(trivial_merge(&[0, 1, 2, 2, 3]), None);
799 assert_eq!(trivial_merge(&[0, 1, 2, 3, 0]), None);
800 assert_eq!(trivial_merge(&[0, 1, 2, 3, 1]), None);
801 assert_eq!(trivial_merge(&[0, 1, 2, 3, 2]), None);
802 assert_eq!(trivial_merge(&[0, 1, 2, 3, 3]), None);
803 assert_eq!(trivial_merge(&[0, 1, 2, 3, 4]), None);
804 }
805
806 #[test]
807 fn test_legacy_form_conversion() {
808 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
809 where
810 T: Clone + PartialEq + std::fmt::Debug,
811 {
812 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
813 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
814 }
815 test_equivalent(
817 (vec![], vec![0]),
818 Merge::from_removes_adds(vec![], vec![Some(0)]),
819 );
820 test_equivalent(
822 (vec![0], vec![1, 2]),
823 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
824 );
825 test_equivalent(
827 (vec![0], vec![1]),
828 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
829 );
830 test_equivalent(
832 (vec![], vec![0, 1]),
833 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
834 );
835 test_equivalent(
837 (vec![0, 1], vec![2, 3, 4]),
838 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
839 );
840 test_equivalent(
842 (vec![0, 1], vec![]),
843 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
844 );
845 }
846
847 #[test]
848 fn test_as_resolved() {
849 assert_eq!(
850 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
851 Some(&0)
852 );
853 assert_eq!(
855 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
856 None
857 );
858 }
859
860 #[test]
861 fn test_get_simplified_mapping() {
862 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
864 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
866 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
867 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
868 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
869 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
870 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
872 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
873 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
874 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
875 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
876 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
877 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
878 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
879 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
880 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
881 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
882 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
883 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
884 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
885 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
886 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
887 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
888 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
889 assert_eq!(
890 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
891 vec![0, 1, 2, 3, 4]
892 );
893 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
894 assert_eq!(
895 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
896 vec![0, 1, 2, 3, 4]
897 );
898 assert_eq!(
899 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
900 vec![0, 1, 2, 3, 4]
901 );
902 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
903 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
904 assert_eq!(
905 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
906 vec![0, 1, 2, 3, 4]
907 );
908 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
909 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
910 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
911 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
912 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
913 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
914 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
915 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
916 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
917 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
918 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
919 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
920 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
921 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
922 assert_eq!(
923 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
924 vec![0, 1, 2, 3, 4]
925 );
926 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
927 assert_eq!(
928 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
929 vec![0, 1, 2, 3, 4]
930 );
931 assert_eq!(
932 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
933 vec![0, 1, 2, 3, 4]
934 );
935 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
936 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
937 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
938 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
939 assert_eq!(
940 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
941 vec![0, 1, 2, 3, 4]
942 );
943 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
944 assert_eq!(
945 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
946 vec![0, 1, 2, 3, 4]
947 );
948 assert_eq!(
949 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
950 vec![0, 3, 4, 5, 2]
951 );
952 assert_eq!(
953 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
954 vec![0, 1, 2, 3, 4]
955 );
956 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
957 }
958
959 #[test]
960 fn test_simplify() {
961 assert_eq!(c(&[0]).simplify(), c(&[0]));
963 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
965 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
966 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
967 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
968 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
969 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
971 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
972 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
973 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
974 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
975 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
976 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
977 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
978 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
979 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
980 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
981 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
982 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
983 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
984 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
985 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
986 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
987 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
988 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
989 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
990 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
991 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
992 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
993 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
994 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
995 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
996 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
997 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
998 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
999 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1000 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1001 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1002 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1003 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1004 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1005 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1006 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1007 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1008 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1009 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1010 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1011 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1012 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1013 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1014 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1015 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1016 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1017 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1018 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1019 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1020 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1021 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1022 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1023 }
1024
1025 #[test]
1026 fn test_update_from_simplified() {
1027 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1029 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1031 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1032 assert_eq!(
1033 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1034 c(&[2, 1, 3])
1035 );
1036 assert_eq!(
1038 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1039 c(&[0, 0, 0, 0, 1])
1040 );
1041 assert_eq!(
1042 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1043 c(&[0, 0, 2, 3, 1])
1044 );
1045 assert_eq!(
1046 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1047 c(&[0, 3, 1, 0, 2])
1048 );
1049 assert_eq!(
1050 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1051 c(&[3, 1, 4, 2, 5])
1052 );
1053
1054 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1055 assert_eq!(
1058 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1059 c(&[0, 0, 10, 1, 11, 2, 4])
1060 );
1061 }
1062
1063 #[test]
1064 fn test_merge_invariants() {
1065 fn check_invariants(terms: &[u32]) {
1066 let merge = Merge::from_vec(terms.to_vec());
1067 assert_eq!(
1069 merge.simplify().simplify(),
1070 merge.simplify(),
1071 "simplify() not idempotent for {merge:?}"
1072 );
1073 assert_eq!(
1075 merge.simplify().resolve_trivial(),
1076 merge.resolve_trivial(),
1077 "simplify() changed result of resolve_trivial() for {merge:?}"
1078 );
1079 }
1080 check_invariants(&[0]);
1082 for i in 0..=1 {
1083 for j in 0..=i + 1 {
1084 check_invariants(&[i, 0, j]);
1086 for k in 0..=j + 1 {
1087 for l in 0..=k + 1 {
1088 check_invariants(&[0, i, j, k, l]);
1090 }
1091 }
1092 }
1093 }
1094 }
1095
1096 #[test]
1097 fn test_swap_remove() {
1098 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1099 assert_eq!(x.swap_remove(0, 1), (1, 2));
1100 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1101 assert_eq!(x.swap_remove(1, 0), (3, 0));
1102 assert_eq!(x, c(&[4, 5, 6]));
1103 assert_eq!(x.swap_remove(0, 1), (5, 6));
1104 assert_eq!(x, c(&[4]));
1105 }
1106
1107 #[test]
1108 fn test_pad_to() {
1109 let mut x = c(&[1]);
1110 x.pad_to(3, &2);
1111 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1112 x.pad_to(1, &3);
1114 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1115 }
1116
1117 #[test]
1118 fn test_iter() {
1119 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1121 assert_eq!(
1123 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1124 vec![&1, &2, &3, &4, &5]
1125 );
1126 }
1127
1128 #[test]
1129 fn test_from_iter() {
1130 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1132 assert_eq!(
1134 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1135 c(&[1, 2, 3, 4, 5])
1136 );
1137 }
1138
1139 #[test]
1140 #[should_panic]
1141 fn test_from_iter_empty() {
1142 MergeBuilder::from_iter([1; 0]).build();
1143 }
1144
1145 #[test]
1146 #[should_panic]
1147 fn test_from_iter_even() {
1148 MergeBuilder::from_iter([1, 2]).build();
1149 }
1150
1151 #[test]
1152 fn test_extend() {
1153 let mut builder: MergeBuilder<i32> = Default::default();
1155 builder.extend([1]);
1156 assert_eq!(builder.build(), c(&[1]));
1157 let mut builder: MergeBuilder<i32> = Default::default();
1159 builder.extend([1, 2]);
1160 builder.extend([3, 4, 5]);
1161 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1162 }
1163
1164 #[test]
1165 fn test_map() {
1166 fn increment(i: &i32) -> i32 {
1167 i + 1
1168 }
1169 assert_eq!(c(&[1]).map(increment), c(&[2]));
1171 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1173 }
1174
1175 #[test]
1176 fn test_try_map() {
1177 fn sqrt(i: &i32) -> Result<i32, ()> {
1178 if *i >= 0 {
1179 Ok((*i as f64).sqrt() as i32)
1180 } else {
1181 Err(())
1182 }
1183 }
1184 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1186 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1187 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1189 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1190 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1191 }
1192
1193 #[test]
1194 fn test_flatten() {
1195 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1197 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1199 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1201 assert_eq!(
1203 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1204 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1205 );
1206 }
1207}