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)]
112pub struct Merge<T> {
113 values: SmallVec<[T; 1]>,
115}
116
117impl<T: Debug> Debug for Merge<T> {
118 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
119 if let Some(value) = self.as_resolved() {
122 f.debug_tuple("Resolved").field(value).finish()
123 } else {
124 f.debug_tuple("Conflicted").field(&self.values).finish()
125 }
126 }
127}
128
129impl<T> Merge<T> {
130 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
133 let values = values.into();
134 assert!(values.len() % 2 != 0, "must have an odd number of terms");
135 Merge { values }
136 }
137
138 pub fn from_removes_adds(
140 removes: impl IntoIterator<Item = T>,
141 adds: impl IntoIterator<Item = T>,
142 ) -> Self {
143 let removes = removes.into_iter();
144 let mut adds = adds.into_iter();
145 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
146 values.push(adds.next().expect("must have at least one add"));
147 for diff in removes.zip_longest(adds) {
148 let (remove, add) = diff.both().expect("must have one more adds than removes");
149 values.extend([remove, add]);
150 }
151 Merge { values }
152 }
153
154 pub const fn resolved(value: T) -> Self {
156 Merge {
157 values: smallvec_inline![value],
158 }
159 }
160
161 pub fn from_legacy_form(
164 removes: impl IntoIterator<Item = T>,
165 adds: impl IntoIterator<Item = T>,
166 ) -> Merge<Option<T>> {
167 let removes = removes.into_iter();
168 let mut adds = adds.into_iter().fuse();
169 let mut values = smallvec_inline![adds.next()];
170 for diff in removes.zip_longest(adds) {
171 let (remove, add) = diff.map_any(Some, Some).or_default();
172 values.extend([remove, add]);
173 }
174 Merge { values }
175 }
176
177 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
179 self.values[1..].iter().step_by(2)
180 }
181
182 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
184 self.values.iter().step_by(2)
185 }
186
187 pub fn first(&self) -> &T {
189 &self.values[0]
190 }
191
192 pub fn get_remove(&self, index: usize) -> Option<&T> {
195 self.values.get(index * 2 + 1)
196 }
197
198 pub fn get_add(&self, index: usize) -> Option<&T> {
202 self.values.get(index * 2)
203 }
204
205 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
208 let add = self.values.swap_remove(add_index * 2);
210 let remove = self.values.swap_remove(remove_index * 2 + 1);
211 (remove, add)
212 }
213
214 pub fn num_sides(&self) -> usize {
216 self.values.len() / 2 + 1
217 }
218
219 pub fn is_resolved(&self) -> bool {
221 self.values.len() == 1
222 }
223
224 pub fn as_resolved(&self) -> Option<&T> {
227 if let [value] = &self.values[..] {
228 Some(value)
229 } else {
230 None
231 }
232 }
233
234 pub fn into_resolved(mut self) -> Result<T, Merge<T>> {
237 if self.values.len() == 1 {
238 Ok(self.values.pop().unwrap())
239 } else {
240 Err(self)
241 }
242 }
243
244 fn get_simplified_mapping(&self) -> Vec<usize>
250 where
251 T: PartialEq,
252 {
253 let unsimplified_len = self.values.len();
254 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
255
256 let mut add_index = 0;
257 while add_index < simplified_to_original_indices.len() {
258 let add = &self.values[simplified_to_original_indices[add_index]];
259 let mut remove_indices = simplified_to_original_indices
260 .iter()
261 .enumerate()
262 .skip(1)
263 .step_by(2);
264 if let Some((remove_index, _)) = remove_indices
265 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
266 {
267 simplified_to_original_indices.swap(remove_index + 1, add_index);
270 simplified_to_original_indices.drain(remove_index..remove_index + 2);
271 } else {
272 add_index += 2;
273 }
274 }
275
276 simplified_to_original_indices
277 }
278
279 #[must_use]
282 pub fn simplify(&self) -> Self
283 where
284 T: PartialEq + Clone,
285 {
286 let mapping = self.get_simplified_mapping();
287 let values = mapping
289 .iter()
290 .map(|index| self.values[*index].clone())
291 .collect();
292 Merge { values }
293 }
294
295 pub fn update_from_simplified(mut self, simplified: Merge<T>) -> Self
297 where
298 T: PartialEq,
299 {
300 let mapping = self.get_simplified_mapping();
301 assert_eq!(mapping.len(), simplified.values.len());
302 for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
303 self.values[index] = value;
304 }
305 self
306 }
307
308 pub fn resolve_trivial(&self) -> Option<&T>
311 where
312 T: Eq + Hash,
313 {
314 trivial_merge(&self.values)
315 }
316
317 pub fn pad_to(&mut self, num_sides: usize, value: &T)
320 where
321 T: Clone,
322 {
323 if num_sides <= self.num_sides() {
324 return;
325 }
326 self.values.resize(num_sides * 2 - 1, value.clone());
327 }
328
329 pub fn as_slice(&self) -> &[T] {
333 &self.values
334 }
335
336 pub fn iter(&self) -> slice::Iter<'_, T> {
340 self.values.iter()
341 }
342
343 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
345 self.values.iter_mut()
346 }
347
348 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
350 let values = self.values.iter().map(f).collect();
351 Merge { values }
352 }
353
354 pub fn try_map<'a, U, E>(
357 &'a self,
358 f: impl FnMut(&'a T) -> Result<U, E>,
359 ) -> Result<Merge<U>, E> {
360 let values = self.values.iter().map(f).try_collect()?;
361 Ok(Merge { values })
362 }
363
364 pub async fn try_map_async<'a, F, U, E>(
368 &'a self,
369 f: impl FnMut(&'a T) -> F,
370 ) -> Result<Merge<U>, E>
371 where
372 F: Future<Output = Result<U, E>>,
373 {
374 let values = try_join_all(self.values.iter().map(f)).await?;
375 Ok(Merge {
376 values: values.into(),
377 })
378 }
379}
380
381#[derive(Clone, Debug, PartialEq, Eq)]
390pub struct MergeBuilder<T> {
391 values: SmallVec<[T; 1]>,
392}
393
394impl<T> Default for MergeBuilder<T> {
395 fn default() -> Self {
396 Self {
397 values: Default::default(),
398 }
399 }
400}
401
402impl<T> MergeBuilder<T> {
403 pub fn build(self) -> Merge<T> {
406 Merge::from_vec(self.values)
407 }
408}
409
410impl<T> IntoIterator for Merge<T> {
411 type Item = T;
412 type IntoIter = smallvec::IntoIter<[T; 1]>;
413
414 fn into_iter(self) -> Self::IntoIter {
415 self.values.into_iter()
416 }
417}
418
419impl<T> FromIterator<T> for MergeBuilder<T> {
420 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
421 let mut builder = MergeBuilder::default();
422 builder.extend(iter);
423 builder
424 }
425}
426
427impl<T> Extend<T> for MergeBuilder<T> {
428 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
429 self.values.extend(iter);
430 }
431}
432
433impl<T> Merge<Option<T>> {
434 pub fn absent() -> Self {
436 Self::resolved(None)
437 }
438
439 pub fn normal(value: T) -> Self {
441 Self::resolved(Some(value))
442 }
443
444 pub fn is_absent(&self) -> bool {
446 matches!(self.as_resolved(), Some(None))
447 }
448
449 pub fn is_present(&self) -> bool {
451 !self.is_absent()
452 }
453
454 pub fn as_normal(&self) -> Option<&T> {
456 self.as_resolved()?.as_ref()
457 }
458
459 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
463 let mut removes = Vec::with_capacity(self.values.len() / 2);
465 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
466 let mut values = self.values.into_iter();
467 adds.extend(values.next().unwrap());
468 while let Some(remove) = values.next() {
469 removes.extend(remove);
470 adds.extend(values.next().unwrap());
471 }
472 (removes, adds)
473 }
474}
475
476impl<T: Clone> Merge<Option<&T>> {
477 pub fn cloned(&self) -> Merge<Option<T>> {
479 self.map(|value| value.cloned())
480 }
481}
482
483impl<T> Merge<Merge<T>> {
484 pub fn flatten(self) -> Merge<T> {
498 let mut outer_values = self.values.into_iter();
499 let mut result = outer_values.next().unwrap();
500 while let Some(mut remove) = outer_values.next() {
501 remove.values.rotate_left(1);
504 for i in 0..remove.values.len() / 2 {
505 remove.values.swap(i * 2, i * 2 + 1);
506 }
507 result.values.extend(remove.values);
508 let add = outer_values.next().unwrap();
509 result.values.extend(add.values);
510 }
511 result
512 }
513}
514
515impl<T: ContentHash> ContentHash for Merge<T> {
516 fn hash(&self, state: &mut impl DigestUpdate) {
517 self.values.hash(state);
518 }
519}
520
521pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
523
524pub type MergedTreeValue = Merge<Option<TreeValue>>;
531
532impl MergedTreeValue {
533 pub fn from_backend_conflict(conflict: backend::Conflict) -> Self {
536 let removes = conflict.removes.into_iter().map(|term| term.value);
537 let adds = conflict.adds.into_iter().map(|term| term.value);
538 Merge::from_legacy_form(removes, adds)
539 }
540
541 pub fn into_backend_conflict(self) -> backend::Conflict {
545 let (removes, adds) = self.into_legacy_form();
546 let removes = removes
547 .into_iter()
548 .map(|value| backend::ConflictTerm { value })
549 .collect();
550 let adds = adds
551 .into_iter()
552 .map(|value| backend::ConflictTerm { value })
553 .collect();
554 backend::Conflict { removes, adds }
555 }
556}
557
558impl<T> Merge<Option<T>>
559where
560 T: Borrow<TreeValue>,
561{
562 pub fn is_tree(&self) -> bool {
564 self.is_present()
565 && self.iter().all(|value| {
566 matches!(
567 borrow_tree_value(value.as_ref()),
568 Some(TreeValue::Tree(_)) | None
569 )
570 })
571 }
572
573 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
578 let file_ids = self
579 .try_map(|term| match borrow_tree_value(term.as_ref()) {
580 None => Ok(None),
581 Some(TreeValue::File {
582 id,
583 executable: _,
584 copy_id: _,
585 }) => Ok(Some(id.clone())),
586 _ => Err(()),
587 })
588 .ok()?;
589
590 Some(file_ids)
591 }
592
593 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
596 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
597 None => Ok(None),
598 Some(TreeValue::File {
599 id: _,
600 executable,
601 copy_id: _,
602 }) => Ok(Some(*executable)),
603 _ => Err(()),
604 })
605 .ok()
606 }
607
608 pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
611 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
612 None => Ok(None),
613 Some(TreeValue::File {
614 id: _,
615 executable: _,
616 copy_id,
617 }) => Ok(Some(copy_id.clone())),
618 _ => Err(()),
619 })
620 .ok()
621 }
622
623 pub async fn to_tree_merge(
628 &self,
629 store: &Arc<Store>,
630 dir: &RepoPath,
631 ) -> BackendResult<Option<Merge<Tree>>> {
632 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
633 None => Ok(None),
634 Some(TreeValue::Tree(id)) => Ok(Some(id)),
635 Some(_) => Err(()),
636 });
637 if let Ok(tree_id_merge) = tree_id_merge {
638 Ok(Some(
639 tree_id_merge
640 .try_map_async(|id| async move {
641 if let Some(id) = id {
642 store.get_tree_async(dir.to_owned(), id).await
643 } else {
644 Ok(Tree::empty(store.clone(), dir.to_owned()))
645 }
646 })
647 .await?,
648 ))
649 } else {
650 Ok(None)
651 }
652 }
653
654 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
660 assert_eq!(self.values.len(), file_ids.values.len());
661 let values = zip(self.iter(), file_ids.iter().cloned())
662 .map(
663 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
664 (
665 Some(TreeValue::File {
666 id: _,
667 executable,
668 copy_id,
669 }),
670 Some(id),
671 ) => Some(TreeValue::File {
672 id,
673 executable: *executable,
674 copy_id: copy_id.clone(),
675 }),
676 (None, None) => None,
677 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
678 },
679 )
680 .collect();
681 Merge { values }
682 }
683
684 pub fn describe(&self) -> String {
686 let mut buf = String::new();
687 writeln!(buf, "Conflict:").unwrap();
688 for term in self.removes().flatten() {
689 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
690 }
691 for term in self.adds().flatten() {
692 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
693 }
694 buf
695 }
696}
697
698fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
699 term.map(|value| value.borrow())
700}
701
702fn describe_conflict_term(value: &TreeValue) -> String {
703 match value {
704 TreeValue::File {
705 id,
706 executable: false,
707 copy_id: _,
708 } => {
709 format!("file with id {id}")
711 }
712 TreeValue::File {
713 id,
714 executable: true,
715 copy_id: _,
716 } => {
717 format!("executable file with id {id}")
719 }
720 TreeValue::Symlink(id) => {
721 format!("symlink with id {id}")
722 }
723 TreeValue::Tree(id) => {
724 format!("tree with id {id}")
725 }
726 TreeValue::GitSubmodule(id) => {
727 format!("Git submodule with id {id}")
728 }
729 TreeValue::Conflict(id) => {
730 format!("Conflict with id {id}")
731 }
732 }
733}
734
735#[cfg(test)]
736mod tests {
737 use super::*;
738
739 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
740 Merge::from_vec(terms.to_vec())
741 }
742
743 #[test]
744 fn test_trivial_merge() {
745 assert_eq!(trivial_merge(&[0]), Some(&0));
746 assert_eq!(trivial_merge(&[0, 0, 0]), Some(&0));
747 assert_eq!(trivial_merge(&[0, 0, 1]), Some(&1));
748 assert_eq!(trivial_merge(&[0, 1, 0]), Some(&0));
749 assert_eq!(trivial_merge(&[0, 1, 1]), Some(&0));
750 assert_eq!(trivial_merge(&[0, 1, 2]), None);
751 assert_eq!(trivial_merge(&[0, 0, 0, 0, 0]), Some(&0));
752 assert_eq!(trivial_merge(&[0, 0, 0, 0, 1]), Some(&1));
753 assert_eq!(trivial_merge(&[0, 0, 0, 1, 0]), Some(&0));
754 assert_eq!(trivial_merge(&[0, 0, 0, 1, 1]), Some(&0));
755 assert_eq!(trivial_merge(&[0, 0, 0, 1, 2]), None);
756 assert_eq!(trivial_merge(&[0, 0, 1, 0, 0]), Some(&1));
757 assert_eq!(trivial_merge(&[0, 0, 1, 0, 1]), Some(&1));
758 assert_eq!(trivial_merge(&[0, 0, 1, 0, 2]), None);
759 assert_eq!(trivial_merge(&[0, 0, 1, 1, 0]), Some(&0));
760 assert_eq!(trivial_merge(&[0, 0, 1, 1, 1]), Some(&1));
761 assert_eq!(trivial_merge(&[0, 0, 1, 1, 2]), Some(&2));
762 assert_eq!(trivial_merge(&[0, 0, 1, 2, 0]), None);
763 assert_eq!(trivial_merge(&[0, 0, 1, 2, 1]), Some(&1));
764 assert_eq!(trivial_merge(&[0, 0, 1, 2, 2]), Some(&1));
765 assert_eq!(trivial_merge(&[0, 0, 1, 2, 3]), None);
766 assert_eq!(trivial_merge(&[0, 1, 0, 0, 0]), Some(&0));
767 assert_eq!(trivial_merge(&[0, 1, 0, 0, 1]), Some(&0));
768 assert_eq!(trivial_merge(&[0, 1, 0, 0, 2]), None);
769 assert_eq!(trivial_merge(&[0, 1, 0, 1, 0]), Some(&0));
770 assert_eq!(trivial_merge(&[0, 1, 0, 1, 1]), Some(&0));
771 assert_eq!(trivial_merge(&[0, 1, 0, 1, 2]), None);
772 assert_eq!(trivial_merge(&[0, 1, 0, 2, 0]), None);
773 assert_eq!(trivial_merge(&[0, 1, 0, 2, 1]), Some(&0));
774 assert_eq!(trivial_merge(&[0, 1, 0, 2, 2]), Some(&0));
775 assert_eq!(trivial_merge(&[0, 1, 0, 2, 3]), None);
776 assert_eq!(trivial_merge(&[0, 1, 1, 0, 0]), Some(&0));
777 assert_eq!(trivial_merge(&[0, 1, 1, 0, 1]), Some(&1));
778 assert_eq!(trivial_merge(&[0, 1, 1, 0, 2]), Some(&2));
779 assert_eq!(trivial_merge(&[0, 1, 1, 1, 0]), Some(&0));
780 assert_eq!(trivial_merge(&[0, 1, 1, 1, 1]), Some(&0));
781 assert_eq!(trivial_merge(&[0, 1, 1, 1, 2]), None);
782 assert_eq!(trivial_merge(&[0, 1, 1, 2, 0]), Some(&0));
783 assert_eq!(trivial_merge(&[0, 1, 1, 2, 1]), None);
784 assert_eq!(trivial_merge(&[0, 1, 1, 2, 2]), Some(&0));
785 assert_eq!(trivial_merge(&[0, 1, 1, 2, 3]), None);
786 assert_eq!(trivial_merge(&[0, 1, 2, 0, 0]), None);
787 assert_eq!(trivial_merge(&[0, 1, 2, 0, 1]), Some(&2));
788 assert_eq!(trivial_merge(&[0, 1, 2, 0, 2]), Some(&2));
789 assert_eq!(trivial_merge(&[0, 1, 2, 0, 3]), None);
790 assert_eq!(trivial_merge(&[0, 1, 2, 1, 0]), None);
791 assert_eq!(trivial_merge(&[0, 1, 2, 1, 1]), None);
792 assert_eq!(trivial_merge(&[0, 1, 2, 1, 2]), None);
793 assert_eq!(trivial_merge(&[0, 1, 2, 1, 3]), None);
794 assert_eq!(trivial_merge(&[0, 1, 2, 2, 0]), Some(&0));
795 assert_eq!(trivial_merge(&[0, 1, 2, 2, 1]), Some(&0));
796 assert_eq!(trivial_merge(&[0, 1, 2, 2, 2]), None);
797 assert_eq!(trivial_merge(&[0, 1, 2, 2, 3]), None);
798 assert_eq!(trivial_merge(&[0, 1, 2, 3, 0]), None);
799 assert_eq!(trivial_merge(&[0, 1, 2, 3, 1]), None);
800 assert_eq!(trivial_merge(&[0, 1, 2, 3, 2]), None);
801 assert_eq!(trivial_merge(&[0, 1, 2, 3, 3]), None);
802 assert_eq!(trivial_merge(&[0, 1, 2, 3, 4]), None);
803 }
804
805 #[test]
806 fn test_legacy_form_conversion() {
807 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
808 where
809 T: Clone + PartialEq + std::fmt::Debug,
810 {
811 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
812 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
813 }
814 test_equivalent(
816 (vec![], vec![0]),
817 Merge::from_removes_adds(vec![], vec![Some(0)]),
818 );
819 test_equivalent(
821 (vec![0], vec![1, 2]),
822 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
823 );
824 test_equivalent(
826 (vec![0], vec![1]),
827 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
828 );
829 test_equivalent(
831 (vec![], vec![0, 1]),
832 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
833 );
834 test_equivalent(
836 (vec![0, 1], vec![2, 3, 4]),
837 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
838 );
839 test_equivalent(
841 (vec![0, 1], vec![]),
842 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
843 );
844 }
845
846 #[test]
847 fn test_as_resolved() {
848 assert_eq!(
849 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
850 Some(&0)
851 );
852 assert_eq!(
854 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
855 None
856 );
857 }
858
859 #[test]
860 fn test_get_simplified_mapping() {
861 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
863 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
865 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
866 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
867 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
868 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
869 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
871 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
872 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
873 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
874 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
875 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
876 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
877 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
878 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
879 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
880 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
881 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
882 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
883 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
884 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
885 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
886 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
887 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
888 assert_eq!(
889 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
890 vec![0, 1, 2, 3, 4]
891 );
892 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
893 assert_eq!(
894 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
895 vec![0, 1, 2, 3, 4]
896 );
897 assert_eq!(
898 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
899 vec![0, 1, 2, 3, 4]
900 );
901 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
902 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
903 assert_eq!(
904 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
905 vec![0, 1, 2, 3, 4]
906 );
907 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
908 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
909 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
910 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
911 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
912 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
913 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
914 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
915 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
916 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
917 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
918 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
919 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
920 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
921 assert_eq!(
922 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
923 vec![0, 1, 2, 3, 4]
924 );
925 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
926 assert_eq!(
927 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
928 vec![0, 1, 2, 3, 4]
929 );
930 assert_eq!(
931 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
932 vec![0, 1, 2, 3, 4]
933 );
934 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
935 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
936 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
937 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
938 assert_eq!(
939 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
940 vec![0, 1, 2, 3, 4]
941 );
942 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
943 assert_eq!(
944 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
945 vec![0, 1, 2, 3, 4]
946 );
947 assert_eq!(
948 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
949 vec![0, 3, 4, 5, 2]
950 );
951 assert_eq!(
952 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
953 vec![0, 1, 2, 3, 4]
954 );
955 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
956 }
957
958 #[test]
959 fn test_simplify() {
960 assert_eq!(c(&[0]).simplify(), c(&[0]));
962 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
964 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
965 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
966 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
967 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
968 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
970 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
971 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
972 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
973 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
974 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
975 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
976 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
977 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
978 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
979 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
980 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
981 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
982 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
983 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
984 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
985 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
986 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
987 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
988 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
989 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
990 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
991 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
992 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
993 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
994 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
995 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
996 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
997 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
998 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
999 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1000 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1001 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1002 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1003 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1004 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1005 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1006 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1007 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1008 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1009 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1010 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1011 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1012 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1013 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1014 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1015 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1016 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1017 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1018 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1019 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1020 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1021 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1022 }
1023
1024 #[test]
1025 fn test_update_from_simplified() {
1026 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1028 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1030 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1031 assert_eq!(
1032 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1033 c(&[2, 1, 3])
1034 );
1035 assert_eq!(
1037 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1038 c(&[0, 0, 0, 0, 1])
1039 );
1040 assert_eq!(
1041 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1042 c(&[0, 0, 2, 3, 1])
1043 );
1044 assert_eq!(
1045 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1046 c(&[0, 3, 1, 0, 2])
1047 );
1048 assert_eq!(
1049 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1050 c(&[3, 1, 4, 2, 5])
1051 );
1052
1053 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1054 assert_eq!(
1057 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1058 c(&[0, 0, 10, 1, 11, 2, 4])
1059 );
1060 }
1061
1062 #[test]
1063 fn test_merge_invariants() {
1064 fn check_invariants(terms: &[u32]) {
1065 let merge = Merge::from_vec(terms.to_vec());
1066 assert_eq!(
1068 merge.simplify().simplify(),
1069 merge.simplify(),
1070 "simplify() not idempotent for {merge:?}"
1071 );
1072 assert_eq!(
1074 merge.simplify().resolve_trivial(),
1075 merge.resolve_trivial(),
1076 "simplify() changed result of resolve_trivial() for {merge:?}"
1077 );
1078 }
1079 check_invariants(&[0]);
1081 for i in 0..=1 {
1082 for j in 0..=i + 1 {
1083 check_invariants(&[i, 0, j]);
1085 for k in 0..=j + 1 {
1086 for l in 0..=k + 1 {
1087 check_invariants(&[0, i, j, k, l]);
1089 }
1090 }
1091 }
1092 }
1093 }
1094
1095 #[test]
1096 fn test_swap_remove() {
1097 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1098 assert_eq!(x.swap_remove(0, 1), (1, 2));
1099 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1100 assert_eq!(x.swap_remove(1, 0), (3, 0));
1101 assert_eq!(x, c(&[4, 5, 6]));
1102 assert_eq!(x.swap_remove(0, 1), (5, 6));
1103 assert_eq!(x, c(&[4]));
1104 }
1105
1106 #[test]
1107 fn test_pad_to() {
1108 let mut x = c(&[1]);
1109 x.pad_to(3, &2);
1110 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1111 x.pad_to(1, &3);
1113 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1114 }
1115
1116 #[test]
1117 fn test_iter() {
1118 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1120 assert_eq!(
1122 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1123 vec![&1, &2, &3, &4, &5]
1124 );
1125 }
1126
1127 #[test]
1128 fn test_from_iter() {
1129 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1131 assert_eq!(
1133 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1134 c(&[1, 2, 3, 4, 5])
1135 );
1136 }
1137
1138 #[test]
1139 #[should_panic]
1140 fn test_from_iter_empty() {
1141 MergeBuilder::from_iter([1; 0]).build();
1142 }
1143
1144 #[test]
1145 #[should_panic]
1146 fn test_from_iter_even() {
1147 MergeBuilder::from_iter([1, 2]).build();
1148 }
1149
1150 #[test]
1151 fn test_extend() {
1152 let mut builder: MergeBuilder<i32> = Default::default();
1154 builder.extend([1]);
1155 assert_eq!(builder.build(), c(&[1]));
1156 let mut builder: MergeBuilder<i32> = Default::default();
1158 builder.extend([1, 2]);
1159 builder.extend([3, 4, 5]);
1160 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1161 }
1162
1163 #[test]
1164 fn test_map() {
1165 fn increment(i: &i32) -> i32 {
1166 i + 1
1167 }
1168 assert_eq!(c(&[1]).map(increment), c(&[2]));
1170 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1172 }
1173
1174 #[test]
1175 fn test_try_map() {
1176 fn sqrt(i: &i32) -> Result<i32, ()> {
1177 if *i >= 0 {
1178 Ok((*i as f64).sqrt() as i32)
1179 } else {
1180 Err(())
1181 }
1182 }
1183 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1185 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1186 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1188 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1189 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1190 }
1191
1192 #[test]
1193 fn test_flatten() {
1194 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1196 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1198 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1200 assert_eq!(
1202 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1203 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1204 );
1205 }
1206}