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::FileId;
37use crate::backend::TreeValue;
38use crate::content_hash::ContentHash;
39use crate::content_hash::DigestUpdate;
40use crate::repo_path::RepoPath;
41use crate::store::Store;
42use crate::tree::Tree;
43
44pub fn trivial_merge<T>(values: &[T]) -> Option<&T>
47where
48 T: Eq + Hash,
49{
50 assert!(
51 values.len() % 2 == 1,
52 "trivial_merge() requires an odd number of terms"
53 );
54 if let [add] = values {
56 return Some(add);
57 } else if let [add0, remove, add1] = values {
58 return if add0 == add1 {
59 Some(add0)
60 } else if add0 == remove {
61 Some(add1)
62 } else if add1 == remove {
63 Some(add0)
64 } else {
65 None
66 };
67 }
68
69 let mut counts: HashMap<&T, i32> = HashMap::new();
73 for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
74 counts.entry(value).and_modify(|e| *e += n).or_insert(n);
75 }
76
77 counts.retain(|_, count| *count != 0);
80 if counts.len() == 1 {
81 let (value, count) = counts.into_iter().next().unwrap();
83 assert_eq!(count, 1);
84 Some(value)
85 } else if counts.len() == 2 {
86 let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
94 assert_eq!(count1 + count2, 1);
95 if count1 > 0 {
96 Some(value1)
97 } else {
98 Some(value2)
99 }
100 } else {
101 None
102 }
103}
104
105#[derive(PartialEq, Eq, Hash, Clone)]
111pub struct Merge<T> {
112 values: SmallVec<[T; 1]>,
114}
115
116impl<T: Debug> Debug for Merge<T> {
117 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
118 if let Some(value) = self.as_resolved() {
121 f.debug_tuple("Resolved").field(value).finish()
122 } else {
123 f.debug_tuple("Conflicted").field(&self.values).finish()
124 }
125 }
126}
127
128impl<T> Merge<T> {
129 pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
132 let values = values.into();
133 assert!(values.len() % 2 != 0, "must have an odd number of terms");
134 Merge { values }
135 }
136
137 pub fn from_removes_adds(
139 removes: impl IntoIterator<Item = T>,
140 adds: impl IntoIterator<Item = T>,
141 ) -> Self {
142 let removes = removes.into_iter();
143 let mut adds = adds.into_iter();
144 let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
145 values.push(adds.next().expect("must have at least one add"));
146 for diff in removes.zip_longest(adds) {
147 let (remove, add) = diff.both().expect("must have one more adds than removes");
148 values.extend([remove, add]);
149 }
150 Merge { values }
151 }
152
153 pub const fn resolved(value: T) -> Self {
155 Merge {
156 values: smallvec_inline![value],
157 }
158 }
159
160 pub fn from_legacy_form(
163 removes: impl IntoIterator<Item = T>,
164 adds: impl IntoIterator<Item = T>,
165 ) -> Merge<Option<T>> {
166 let removes = removes.into_iter();
167 let mut adds = adds.into_iter().fuse();
168 let mut values = smallvec_inline![adds.next()];
169 for diff in removes.zip_longest(adds) {
170 let (remove, add) = diff.map_any(Some, Some).or_default();
171 values.extend([remove, add]);
172 }
173 Merge { values }
174 }
175
176 pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
178 self.values[1..].iter().step_by(2)
179 }
180
181 pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
183 self.values.iter().step_by(2)
184 }
185
186 pub fn first(&self) -> &T {
188 &self.values[0]
189 }
190
191 pub fn get_remove(&self, index: usize) -> Option<&T> {
194 self.values.get(index * 2 + 1)
195 }
196
197 pub fn get_add(&self, index: usize) -> Option<&T> {
201 self.values.get(index * 2)
202 }
203
204 pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
207 let add = self.values.swap_remove(add_index * 2);
209 let remove = self.values.swap_remove(remove_index * 2 + 1);
210 (remove, add)
211 }
212
213 pub fn num_sides(&self) -> usize {
215 self.values.len() / 2 + 1
216 }
217
218 pub fn is_resolved(&self) -> bool {
220 self.values.len() == 1
221 }
222
223 pub fn as_resolved(&self) -> Option<&T> {
226 if let [value] = &self.values[..] {
227 Some(value)
228 } else {
229 None
230 }
231 }
232
233 pub fn into_resolved(mut self) -> Result<T, Merge<T>> {
236 if self.values.len() == 1 {
237 Ok(self.values.pop().unwrap())
238 } else {
239 Err(self)
240 }
241 }
242
243 fn get_simplified_mapping(&self) -> Vec<usize>
249 where
250 T: PartialEq,
251 {
252 let unsimplified_len = self.values.len();
253 let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
254
255 let mut add_index = 0;
256 while add_index < simplified_to_original_indices.len() {
257 let add = &self.values[simplified_to_original_indices[add_index]];
258 let mut remove_indices = simplified_to_original_indices
259 .iter()
260 .enumerate()
261 .skip(1)
262 .step_by(2);
263 if let Some((remove_index, _)) = remove_indices
264 .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
265 {
266 simplified_to_original_indices.swap(remove_index + 1, add_index);
269 simplified_to_original_indices.drain(remove_index..remove_index + 2);
270 } else {
271 add_index += 2;
272 }
273 }
274
275 simplified_to_original_indices
276 }
277
278 #[must_use]
281 pub fn simplify(&self) -> Self
282 where
283 T: PartialEq + Clone,
284 {
285 let mapping = self.get_simplified_mapping();
286 let values = mapping
288 .iter()
289 .map(|index| self.values[*index].clone())
290 .collect();
291 Merge { values }
292 }
293
294 pub fn update_from_simplified(mut self, simplified: Merge<T>) -> Self
296 where
297 T: PartialEq,
298 {
299 let mapping = self.get_simplified_mapping();
300 assert_eq!(mapping.len(), simplified.values.len());
301 for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
302 self.values[index] = value;
303 }
304 self
305 }
306
307 pub fn resolve_trivial(&self) -> Option<&T>
310 where
311 T: Eq + Hash,
312 {
313 trivial_merge(&self.values)
314 }
315
316 pub fn pad_to(&mut self, num_sides: usize, value: &T)
319 where
320 T: Clone,
321 {
322 if num_sides <= self.num_sides() {
323 return;
324 }
325 self.values.resize(num_sides * 2 - 1, value.clone());
326 }
327
328 pub fn as_slice(&self) -> &[T] {
332 &self.values
333 }
334
335 pub fn iter(&self) -> slice::Iter<'_, T> {
339 self.values.iter()
340 }
341
342 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
344 self.values.iter_mut()
345 }
346
347 pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
349 let values = self.values.iter().map(f).collect();
350 Merge { values }
351 }
352
353 pub fn try_map<'a, U, E>(
356 &'a self,
357 f: impl FnMut(&'a T) -> Result<U, E>,
358 ) -> Result<Merge<U>, E> {
359 let values = self.values.iter().map(f).try_collect()?;
360 Ok(Merge { values })
361 }
362
363 pub async fn try_map_async<'a, F, U, E>(
367 &'a self,
368 f: impl FnMut(&'a T) -> F,
369 ) -> Result<Merge<U>, E>
370 where
371 F: Future<Output = Result<U, E>>,
372 {
373 let values = try_join_all(self.values.iter().map(f)).await?;
374 Ok(Merge {
375 values: values.into(),
376 })
377 }
378}
379
380#[derive(Clone, Debug, PartialEq, Eq)]
389pub struct MergeBuilder<T> {
390 values: SmallVec<[T; 1]>,
391}
392
393impl<T> Default for MergeBuilder<T> {
394 fn default() -> Self {
395 Self {
396 values: Default::default(),
397 }
398 }
399}
400
401impl<T> MergeBuilder<T> {
402 pub fn build(self) -> Merge<T> {
405 Merge::from_vec(self.values)
406 }
407}
408
409impl<T> IntoIterator for Merge<T> {
410 type Item = T;
411 type IntoIter = smallvec::IntoIter<[T; 1]>;
412
413 fn into_iter(self) -> Self::IntoIter {
414 self.values.into_iter()
415 }
416}
417
418impl<T> FromIterator<T> for MergeBuilder<T> {
419 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
420 let mut builder = MergeBuilder::default();
421 builder.extend(iter);
422 builder
423 }
424}
425
426impl<T> Extend<T> for MergeBuilder<T> {
427 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
428 self.values.extend(iter);
429 }
430}
431
432impl<T> Merge<Option<T>> {
433 pub fn absent() -> Self {
435 Self::resolved(None)
436 }
437
438 pub fn normal(value: T) -> Self {
440 Self::resolved(Some(value))
441 }
442
443 pub fn is_absent(&self) -> bool {
445 matches!(self.as_resolved(), Some(None))
446 }
447
448 pub fn is_present(&self) -> bool {
450 !self.is_absent()
451 }
452
453 pub fn as_normal(&self) -> Option<&T> {
455 self.as_resolved()?.as_ref()
456 }
457
458 pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
462 let mut removes = Vec::with_capacity(self.values.len() / 2);
464 let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
465 let mut values = self.values.into_iter();
466 adds.extend(values.next().unwrap());
467 while let Some(remove) = values.next() {
468 removes.extend(remove);
469 adds.extend(values.next().unwrap());
470 }
471 (removes, adds)
472 }
473}
474
475impl<T: Clone> Merge<Option<&T>> {
476 pub fn cloned(&self) -> Merge<Option<T>> {
478 self.map(|value| value.cloned())
479 }
480}
481
482impl<T> Merge<Merge<T>> {
483 pub fn flatten(self) -> Merge<T> {
497 let mut outer_values = self.values.into_iter();
498 let mut result = outer_values.next().unwrap();
499 while let Some(mut remove) = outer_values.next() {
500 remove.values.rotate_left(1);
503 for i in 0..remove.values.len() / 2 {
504 remove.values.swap(i * 2, i * 2 + 1);
505 }
506 result.values.extend(remove.values);
507 let add = outer_values.next().unwrap();
508 result.values.extend(add.values);
509 }
510 result
511 }
512}
513
514impl<T: ContentHash> ContentHash for Merge<T> {
515 fn hash(&self, state: &mut impl DigestUpdate) {
516 self.values.hash(state);
517 }
518}
519
520pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
522
523pub type MergedTreeValue = Merge<Option<TreeValue>>;
530
531impl MergedTreeValue {
532 pub fn from_backend_conflict(conflict: backend::Conflict) -> Self {
535 let removes = conflict.removes.into_iter().map(|term| term.value);
536 let adds = conflict.adds.into_iter().map(|term| term.value);
537 Merge::from_legacy_form(removes, adds)
538 }
539
540 pub fn into_backend_conflict(self) -> backend::Conflict {
544 let (removes, adds) = self.into_legacy_form();
545 let removes = removes
546 .into_iter()
547 .map(|value| backend::ConflictTerm { value })
548 .collect();
549 let adds = adds
550 .into_iter()
551 .map(|value| backend::ConflictTerm { value })
552 .collect();
553 backend::Conflict { removes, adds }
554 }
555}
556
557impl<T> Merge<Option<T>>
558where
559 T: Borrow<TreeValue>,
560{
561 pub fn is_tree(&self) -> bool {
563 self.is_present()
564 && self.iter().all(|value| {
565 matches!(
566 borrow_tree_value(value.as_ref()),
567 Some(TreeValue::Tree(_)) | None
568 )
569 })
570 }
571
572 pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
577 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
578 None => Ok(None),
579 Some(TreeValue::File { id, executable: _ }) => Ok(Some(id.clone())),
580 _ => Err(()),
581 })
582 .ok()
583 }
584
585 pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
588 self.try_map(|term| match borrow_tree_value(term.as_ref()) {
589 None => Ok(None),
590 Some(TreeValue::File { id: _, executable }) => Ok(Some(*executable)),
591 _ => Err(()),
592 })
593 .ok()
594 }
595
596 pub async fn to_tree_merge(
601 &self,
602 store: &Arc<Store>,
603 dir: &RepoPath,
604 ) -> BackendResult<Option<Merge<Tree>>> {
605 let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
606 None => Ok(None),
607 Some(TreeValue::Tree(id)) => Ok(Some(id)),
608 Some(_) => Err(()),
609 });
610 if let Ok(tree_id_merge) = tree_id_merge {
611 Ok(Some(
612 tree_id_merge
613 .try_map_async(|id| async move {
614 if let Some(id) = id {
615 store.get_tree_async(dir.to_owned(), id).await
616 } else {
617 Ok(Tree::empty(store.clone(), dir.to_owned()))
618 }
619 })
620 .await?,
621 ))
622 } else {
623 Ok(None)
624 }
625 }
626
627 pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
633 assert_eq!(self.values.len(), file_ids.values.len());
634 let values = zip(self.iter(), file_ids.iter().cloned())
635 .map(
636 |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
637 (Some(&TreeValue::File { id: _, executable }), Some(id)) => {
638 Some(TreeValue::File { id, executable })
639 }
640 (None, None) => None,
641 (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
642 },
643 )
644 .collect();
645 Merge { values }
646 }
647
648 pub fn describe(&self) -> String {
650 let mut buf = String::new();
651 writeln!(buf, "Conflict:").unwrap();
652 for term in self.removes().flatten() {
653 writeln!(buf, " Removing {}", describe_conflict_term(term.borrow())).unwrap();
654 }
655 for term in self.adds().flatten() {
656 writeln!(buf, " Adding {}", describe_conflict_term(term.borrow())).unwrap();
657 }
658 buf
659 }
660}
661
662fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
663 term.map(|value| value.borrow())
664}
665
666fn describe_conflict_term(value: &TreeValue) -> String {
667 match value {
668 TreeValue::File {
669 id,
670 executable: false,
671 } => {
672 format!("file with id {id}")
673 }
674 TreeValue::File {
675 id,
676 executable: true,
677 } => {
678 format!("executable file with id {id}")
679 }
680 TreeValue::Symlink(id) => {
681 format!("symlink with id {id}")
682 }
683 TreeValue::Tree(id) => {
684 format!("tree with id {id}")
685 }
686 TreeValue::GitSubmodule(id) => {
687 format!("Git submodule with id {id}")
688 }
689 TreeValue::Conflict(id) => {
690 format!("Conflict with id {id}")
691 }
692 }
693}
694
695#[cfg(test)]
696mod tests {
697 use super::*;
698
699 fn c<T: Clone>(terms: &[T]) -> Merge<T> {
700 Merge::from_vec(terms.to_vec())
701 }
702
703 #[test]
704 fn test_trivial_merge() {
705 assert_eq!(trivial_merge(&[0]), Some(&0));
706 assert_eq!(trivial_merge(&[0, 0, 0]), Some(&0));
707 assert_eq!(trivial_merge(&[0, 0, 1]), Some(&1));
708 assert_eq!(trivial_merge(&[0, 1, 0]), Some(&0));
709 assert_eq!(trivial_merge(&[0, 1, 1]), Some(&0));
710 assert_eq!(trivial_merge(&[0, 1, 2]), None);
711 assert_eq!(trivial_merge(&[0, 0, 0, 0, 0]), Some(&0));
712 assert_eq!(trivial_merge(&[0, 0, 0, 0, 1]), Some(&1));
713 assert_eq!(trivial_merge(&[0, 0, 0, 1, 0]), Some(&0));
714 assert_eq!(trivial_merge(&[0, 0, 0, 1, 1]), Some(&0));
715 assert_eq!(trivial_merge(&[0, 0, 0, 1, 2]), None);
716 assert_eq!(trivial_merge(&[0, 0, 1, 0, 0]), Some(&1));
717 assert_eq!(trivial_merge(&[0, 0, 1, 0, 1]), Some(&1));
718 assert_eq!(trivial_merge(&[0, 0, 1, 0, 2]), None);
719 assert_eq!(trivial_merge(&[0, 0, 1, 1, 0]), Some(&0));
720 assert_eq!(trivial_merge(&[0, 0, 1, 1, 1]), Some(&1));
721 assert_eq!(trivial_merge(&[0, 0, 1, 1, 2]), Some(&2));
722 assert_eq!(trivial_merge(&[0, 0, 1, 2, 0]), None);
723 assert_eq!(trivial_merge(&[0, 0, 1, 2, 1]), Some(&1));
724 assert_eq!(trivial_merge(&[0, 0, 1, 2, 2]), Some(&1));
725 assert_eq!(trivial_merge(&[0, 0, 1, 2, 3]), None);
726 assert_eq!(trivial_merge(&[0, 1, 0, 0, 0]), Some(&0));
727 assert_eq!(trivial_merge(&[0, 1, 0, 0, 1]), Some(&0));
728 assert_eq!(trivial_merge(&[0, 1, 0, 0, 2]), None);
729 assert_eq!(trivial_merge(&[0, 1, 0, 1, 0]), Some(&0));
730 assert_eq!(trivial_merge(&[0, 1, 0, 1, 1]), Some(&0));
731 assert_eq!(trivial_merge(&[0, 1, 0, 1, 2]), None);
732 assert_eq!(trivial_merge(&[0, 1, 0, 2, 0]), None);
733 assert_eq!(trivial_merge(&[0, 1, 0, 2, 1]), Some(&0));
734 assert_eq!(trivial_merge(&[0, 1, 0, 2, 2]), Some(&0));
735 assert_eq!(trivial_merge(&[0, 1, 0, 2, 3]), None);
736 assert_eq!(trivial_merge(&[0, 1, 1, 0, 0]), Some(&0));
737 assert_eq!(trivial_merge(&[0, 1, 1, 0, 1]), Some(&1));
738 assert_eq!(trivial_merge(&[0, 1, 1, 0, 2]), Some(&2));
739 assert_eq!(trivial_merge(&[0, 1, 1, 1, 0]), Some(&0));
740 assert_eq!(trivial_merge(&[0, 1, 1, 1, 1]), Some(&0));
741 assert_eq!(trivial_merge(&[0, 1, 1, 1, 2]), None);
742 assert_eq!(trivial_merge(&[0, 1, 1, 2, 0]), Some(&0));
743 assert_eq!(trivial_merge(&[0, 1, 1, 2, 1]), None);
744 assert_eq!(trivial_merge(&[0, 1, 1, 2, 2]), Some(&0));
745 assert_eq!(trivial_merge(&[0, 1, 1, 2, 3]), None);
746 assert_eq!(trivial_merge(&[0, 1, 2, 0, 0]), None);
747 assert_eq!(trivial_merge(&[0, 1, 2, 0, 1]), Some(&2));
748 assert_eq!(trivial_merge(&[0, 1, 2, 0, 2]), Some(&2));
749 assert_eq!(trivial_merge(&[0, 1, 2, 0, 3]), None);
750 assert_eq!(trivial_merge(&[0, 1, 2, 1, 0]), None);
751 assert_eq!(trivial_merge(&[0, 1, 2, 1, 1]), None);
752 assert_eq!(trivial_merge(&[0, 1, 2, 1, 2]), None);
753 assert_eq!(trivial_merge(&[0, 1, 2, 1, 3]), None);
754 assert_eq!(trivial_merge(&[0, 1, 2, 2, 0]), Some(&0));
755 assert_eq!(trivial_merge(&[0, 1, 2, 2, 1]), Some(&0));
756 assert_eq!(trivial_merge(&[0, 1, 2, 2, 2]), None);
757 assert_eq!(trivial_merge(&[0, 1, 2, 2, 3]), None);
758 assert_eq!(trivial_merge(&[0, 1, 2, 3, 0]), None);
759 assert_eq!(trivial_merge(&[0, 1, 2, 3, 1]), None);
760 assert_eq!(trivial_merge(&[0, 1, 2, 3, 2]), None);
761 assert_eq!(trivial_merge(&[0, 1, 2, 3, 3]), None);
762 assert_eq!(trivial_merge(&[0, 1, 2, 3, 4]), None);
763 }
764
765 #[test]
766 fn test_legacy_form_conversion() {
767 fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
768 where
769 T: Clone + PartialEq + std::fmt::Debug,
770 {
771 assert_eq!(merge.clone().into_legacy_form(), legacy_form);
772 assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
773 }
774 test_equivalent(
776 (vec![], vec![0]),
777 Merge::from_removes_adds(vec![], vec![Some(0)]),
778 );
779 test_equivalent(
781 (vec![0], vec![1, 2]),
782 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
783 );
784 test_equivalent(
786 (vec![0], vec![1]),
787 Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
788 );
789 test_equivalent(
791 (vec![], vec![0, 1]),
792 Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
793 );
794 test_equivalent(
796 (vec![0, 1], vec![2, 3, 4]),
797 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
798 );
799 test_equivalent(
801 (vec![0, 1], vec![]),
802 Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
803 );
804 }
805
806 #[test]
807 fn test_as_resolved() {
808 assert_eq!(
809 Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
810 Some(&0)
811 );
812 assert_eq!(
814 Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
815 None
816 );
817 }
818
819 #[test]
820 fn test_get_simplified_mapping() {
821 assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
823 assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
825 assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
826 assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
827 assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
828 assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
829 assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
831 assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
832 assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
833 assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
834 assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
835 assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
836 assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
837 assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
838 assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
839 assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
840 assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
841 assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
842 assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
843 assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
844 assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
845 assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
846 assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
847 assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
848 assert_eq!(
849 c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
850 vec![0, 1, 2, 3, 4]
851 );
852 assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
853 assert_eq!(
854 c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
855 vec![0, 1, 2, 3, 4]
856 );
857 assert_eq!(
858 c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
859 vec![0, 1, 2, 3, 4]
860 );
861 assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
862 assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
863 assert_eq!(
864 c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
865 vec![0, 1, 2, 3, 4]
866 );
867 assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
868 assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
869 assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
870 assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
871 assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
872 assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
873 assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
874 assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
875 assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
876 assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
877 assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
878 assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
879 assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
880 assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
881 assert_eq!(
882 c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
883 vec![0, 1, 2, 3, 4]
884 );
885 assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
886 assert_eq!(
887 c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
888 vec![0, 1, 2, 3, 4]
889 );
890 assert_eq!(
891 c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
892 vec![0, 1, 2, 3, 4]
893 );
894 assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
895 assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
896 assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
897 assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
898 assert_eq!(
899 c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
900 vec![0, 1, 2, 3, 4]
901 );
902 assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
903 assert_eq!(
904 c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
905 vec![0, 1, 2, 3, 4]
906 );
907 assert_eq!(
908 c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
909 vec![0, 3, 4, 5, 2]
910 );
911 assert_eq!(
912 c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
913 vec![0, 1, 2, 3, 4]
914 );
915 assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
916 }
917
918 #[test]
919 fn test_simplify() {
920 assert_eq!(c(&[0]).simplify(), c(&[0]));
922 assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
924 assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
925 assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
926 assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
927 assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
928 assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
930 assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
931 assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
932 assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
933 assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
934 assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
935 assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
936 assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
937 assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
938 assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
939 assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
940 assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
941 assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
942 assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
943 assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
944 assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
945 assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
946 assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
947 assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
948 assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
949 assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
950 assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
951 assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
952 assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
953 assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
954 assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
955 assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
956 assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
957 assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
958 assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
959 assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
960 assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
961 assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
962 assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
963 assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
964 assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
965 assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
966 assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
967 assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
968 assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
969 assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
970 assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
971 assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
972 assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
973 assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
974 assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
975 assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
976 assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
977 assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
978 assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
979 assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
980 assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
981 assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
982 }
983
984 #[test]
985 fn test_update_from_simplified() {
986 assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
988 assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
990 assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
991 assert_eq!(
992 c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
993 c(&[2, 1, 3])
994 );
995 assert_eq!(
997 c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
998 c(&[0, 0, 0, 0, 1])
999 );
1000 assert_eq!(
1001 c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1002 c(&[0, 0, 2, 3, 1])
1003 );
1004 assert_eq!(
1005 c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1006 c(&[0, 3, 1, 0, 2])
1007 );
1008 assert_eq!(
1009 c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1010 c(&[3, 1, 4, 2, 5])
1011 );
1012
1013 assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1014 assert_eq!(
1017 c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1018 c(&[0, 0, 10, 1, 11, 2, 4])
1019 );
1020 }
1021
1022 #[test]
1023 fn test_merge_invariants() {
1024 fn check_invariants(terms: &[u32]) {
1025 let merge = Merge::from_vec(terms.to_vec());
1026 assert_eq!(
1028 merge.simplify().simplify(),
1029 merge.simplify(),
1030 "simplify() not idempotent for {merge:?}"
1031 );
1032 assert_eq!(
1034 merge.simplify().resolve_trivial(),
1035 merge.resolve_trivial(),
1036 "simplify() changed result of resolve_trivial() for {merge:?}"
1037 );
1038 }
1039 check_invariants(&[0]);
1041 for i in 0..=1 {
1042 for j in 0..=i + 1 {
1043 check_invariants(&[i, 0, j]);
1045 for k in 0..=j + 1 {
1046 for l in 0..=k + 1 {
1047 check_invariants(&[0, i, j, k, l]);
1049 }
1050 }
1051 }
1052 }
1053 }
1054
1055 #[test]
1056 fn test_swap_remove() {
1057 let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1058 assert_eq!(x.swap_remove(0, 1), (1, 2));
1059 assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1060 assert_eq!(x.swap_remove(1, 0), (3, 0));
1061 assert_eq!(x, c(&[4, 5, 6]));
1062 assert_eq!(x.swap_remove(0, 1), (5, 6));
1063 assert_eq!(x, c(&[4]));
1064 }
1065
1066 #[test]
1067 fn test_pad_to() {
1068 let mut x = c(&[1]);
1069 x.pad_to(3, &2);
1070 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1071 x.pad_to(1, &3);
1073 assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1074 }
1075
1076 #[test]
1077 fn test_iter() {
1078 assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1080 assert_eq!(
1082 c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1083 vec![&1, &2, &3, &4, &5]
1084 );
1085 }
1086
1087 #[test]
1088 fn test_from_iter() {
1089 assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1091 assert_eq!(
1093 MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1094 c(&[1, 2, 3, 4, 5])
1095 );
1096 }
1097
1098 #[test]
1099 #[should_panic]
1100 fn test_from_iter_empty() {
1101 MergeBuilder::from_iter([1; 0]).build();
1102 }
1103
1104 #[test]
1105 #[should_panic]
1106 fn test_from_iter_even() {
1107 MergeBuilder::from_iter([1, 2]).build();
1108 }
1109
1110 #[test]
1111 fn test_extend() {
1112 let mut builder: MergeBuilder<i32> = Default::default();
1114 builder.extend([1]);
1115 assert_eq!(builder.build(), c(&[1]));
1116 let mut builder: MergeBuilder<i32> = Default::default();
1118 builder.extend([1, 2]);
1119 builder.extend([3, 4, 5]);
1120 assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1121 }
1122
1123 #[test]
1124 fn test_map() {
1125 fn increment(i: &i32) -> i32 {
1126 i + 1
1127 }
1128 assert_eq!(c(&[1]).map(increment), c(&[2]));
1130 assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1132 }
1133
1134 #[test]
1135 fn test_try_map() {
1136 fn sqrt(i: &i32) -> Result<i32, ()> {
1137 if *i >= 0 {
1138 Ok((*i as f64).sqrt() as i32)
1139 } else {
1140 Err(())
1141 }
1142 }
1143 assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1145 assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1146 assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1148 assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1149 assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1150 }
1151
1152 #[test]
1153 fn test_flatten() {
1154 assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1156 assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1158 assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1160 assert_eq!(
1162 c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1163 c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1164 );
1165 }
1166}