jj_lib/
merge.rs

1// Copyright 2023 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Generic algorithms for working with merged values, plus specializations for
16//! some common types of merged values.
17
18use 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
44/// Attempt to resolve trivial conflicts between the inputs. There must be
45/// an odd number of terms.
46pub 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    // Optimize the common cases of 3-way merge and 1-way (non-)merge
55    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    // Number of occurrences of each value, with positive indexes counted as +1 and
70    // negative as -1, thereby letting positive and negative terms with the same
71    // value (i.e. key in the map) cancel each other.
72    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    // Collect non-zero value. Values with a count of 0 means that they have
78    // cancelled out.
79    counts.retain(|_, count| *count != 0);
80    if counts.len() == 1 {
81        // If there is a single value with a count of 1 left, then that is the result.
82        let (value, count) = counts.into_iter().next().unwrap();
83        assert_eq!(count, 1);
84        Some(value)
85    } else if counts.len() == 2 {
86        // All sides made the same change.
87        // This matches what Git and Mercurial do (in the 3-way case at least), but not
88        // what Darcs does. It means that repeated 3-way merging of multiple trees may
89        // give different results depending on the order of merging.
90        // TODO: Consider removing this special case, making the algorithm more strict,
91        // and maybe add a more lenient version that is used when the user explicitly
92        // asks for conflict resolution.
93        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/// A generic representation of merged values.
106///
107/// There is exactly one more `adds()` than `removes()`. When interpreted as a
108/// series of diffs, the merge's (i+1)-st add is matched with the i-th
109/// remove. The zeroth add is considered a diff from the non-existent state.
110#[derive(PartialEq, Eq, Hash, Clone)]
111pub struct Merge<T> {
112    /// Alternates between positive and negative terms, starting with positive.
113    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        // Format like an enum with two variants to make it less verbose in the common
119        // case of a resolved state.
120        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    /// Creates a `Merge` from the given values, in which positive and negative
130    /// terms alternate.
131    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    /// Creates a new merge object from the given removes and adds.
138    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    /// Creates a `Merge` with a single resolved value.
154    pub const fn resolved(value: T) -> Self {
155        Merge {
156            values: smallvec_inline![value],
157        }
158    }
159
160    /// Create a `Merge` from a `removes` and `adds`, padding with `None` to
161    /// make sure that there is exactly one more `adds` than `removes`.
162    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    /// The removed values, also called negative terms.
177    pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
178        self.values[1..].iter().step_by(2)
179    }
180
181    /// The added values, also called positive terms.
182    pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
183        self.values.iter().step_by(2)
184    }
185
186    /// Returns the zeroth added value, which is guaranteed to exist.
187    pub fn first(&self) -> &T {
188        &self.values[0]
189    }
190
191    /// Returns the `index`-th removed value, which is considered belonging to
192    /// the `index`-th diff pair.
193    pub fn get_remove(&self, index: usize) -> Option<&T> {
194        self.values.get(index * 2 + 1)
195    }
196
197    /// Returns the `index`-th added value, which is considered belonging to the
198    /// `index-1`-th diff pair. The zeroth add is a diff from the non-existent
199    /// state.
200    pub fn get_add(&self, index: usize) -> Option<&T> {
201        self.values.get(index * 2)
202    }
203
204    /// Removes the specified "removed"/"added" values. The removed slots are
205    /// replaced by the last "removed"/"added" values.
206    pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
207        // Swap with the last "added" and "removed" values in order.
208        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    /// The number of positive terms in the conflict.
214    pub fn num_sides(&self) -> usize {
215        self.values.len() / 2 + 1
216    }
217
218    /// Whether this merge is resolved. Does not resolve trivial merges.
219    pub fn is_resolved(&self) -> bool {
220        self.values.len() == 1
221    }
222
223    /// Returns the resolved value, if this merge is resolved. Does not
224    /// resolve trivial merges.
225    pub fn as_resolved(&self) -> Option<&T> {
226        if let [value] = &self.values[..] {
227            Some(value)
228        } else {
229            None
230        }
231    }
232
233    /// Returns the resolved value, if this merge is resolved. Otherwise returns
234    /// the merge itself as an `Err`. Does not resolve trivial merges.
235    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    /// Returns a vector mapping of a value's index in the simplified merge to
244    /// its original index in the unsimplified merge.
245    ///
246    /// The merge is simplified by removing identical values in add and remove
247    /// values.
248    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                // Align the current "add" value to the `remove_index/2`-th diff, then
267                // delete the diff pair.
268                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    /// Simplify the merge by joining diffs like A->B and B->C into A->C.
279    /// Also drops trivial diffs like A->A.
280    #[must_use]
281    pub fn simplify(&self) -> Self
282    where
283        T: PartialEq + Clone,
284    {
285        let mapping = self.get_simplified_mapping();
286        // Reorder values based on their new indices in the simplified merge.
287        let values = mapping
288            .iter()
289            .map(|index| self.values[*index].clone())
290            .collect();
291        Merge { values }
292    }
293
294    /// Updates the merge based on the given simplified merge.
295    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    /// If this merge can be trivially resolved, returns the value it resolves
308    /// to.
309    pub fn resolve_trivial(&self) -> Option<&T>
310    where
311        T: Eq + Hash,
312    {
313        trivial_merge(&self.values)
314    }
315
316    /// Pads this merge with to the specified number of sides with the specified
317    /// value. No-op if the requested size is not larger than the current size.
318    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    /// Returns a slice containing the terms. The items will alternate between
329    /// positive and negative terms, starting with positive (since there's one
330    /// more of those).
331    pub fn as_slice(&self) -> &[T] {
332        &self.values
333    }
334
335    /// Returns an iterator over references to the terms. The items will
336    /// alternate between positive and negative terms, starting with
337    /// positive (since there's one more of those).
338    pub fn iter(&self) -> slice::Iter<'_, T> {
339        self.values.iter()
340    }
341
342    /// A version of `Merge::iter()` that iterates over mutable references.
343    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
344        self.values.iter_mut()
345    }
346
347    /// Creates a new merge by applying `f` to each remove and add.
348    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    /// Creates a new merge by applying `f` to each remove and add, returning
354    /// `Err if `f` returns `Err` for any of them.
355    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    /// Creates a new merge by applying the async function `f` to each remove
364    /// and add, running them concurrently, and returning `Err if `f`
365    /// returns `Err` for any of them.
366    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/// Helper for consuming items from an iterator and then creating a `Merge`.
381///
382/// By not collecting directly into `Merge`, we can avoid creating invalid
383/// instances of it. If we had `Merge::from_iter()` we would need to allow it to
384/// accept iterators of any length (including 0). We couldn't make it panic on
385/// even lengths because we can get passed such iterators from e.g.
386/// `Option::from_iter()`. By collecting into `MergeBuilder` instead, we move
387/// the checking until after `from_iter()` (to `MergeBuilder::build()`).
388#[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    /// Requires that exactly one more "adds" than "removes" have been added to
403    /// this builder.
404    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    /// Creates a resolved merge with a value of `None`.
434    pub fn absent() -> Self {
435        Self::resolved(None)
436    }
437
438    /// Creates a resolved merge with a value of `Some(value)`.
439    pub fn normal(value: T) -> Self {
440        Self::resolved(Some(value))
441    }
442
443    /// Whether this represents a resolved value of `None`.
444    pub fn is_absent(&self) -> bool {
445        matches!(self.as_resolved(), Some(None))
446    }
447
448    /// The opposite of `is_absent()`.
449    pub fn is_present(&self) -> bool {
450        !self.is_absent()
451    }
452
453    /// Returns the value if this is present and non-conflicting.
454    pub fn as_normal(&self) -> Option<&T> {
455        self.as_resolved()?.as_ref()
456    }
457
458    /// Creates lists of `removes` and `adds` from a `Merge` by dropping
459    /// `None` values. Note that the conversion is lossy: the order of `None`
460    /// values is not preserved when converting back to a `Merge`.
461    pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
462        // Allocate the maximum size assuming there would be few `None`s.
463        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    /// Creates a new merge by cloning inner `Option<&T>`s.
477    pub fn cloned(&self) -> Merge<Option<T>> {
478        self.map(|value| value.cloned())
479    }
480}
481
482impl<T> Merge<Merge<T>> {
483    /// Flattens a nested merge into a regular merge.
484    ///
485    /// Let's say we have a 3-way merge of 3-way merges like this:
486    ///
487    /// 4 5   7 8
488    ///  3     6
489    ///    1 2
490    ///     0
491    ///
492    /// Flattening that results in this 9-way merge:
493    ///
494    /// 4 5 0 7 8
495    ///  3 2 1 6
496    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            // Add removes reversed, and with the first element moved last, so we preserve
501            // the diffs
502            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
520/// Borrowed `MergedTreeValue`.
521pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
522
523/// The value at a given path in a commit.
524///
525/// It depends on the context whether it can be absent
526/// (`Merge::is_absent()`). For example, when getting the value at a
527/// specific path, it may be, but when iterating over entries in a
528/// tree, it shouldn't be.
529pub type MergedTreeValue = Merge<Option<TreeValue>>;
530
531impl MergedTreeValue {
532    /// Create a `Merge` from a `backend::Conflict`, padding with `None` to
533    /// make sure that there is exactly one more `adds()` than `removes()`.
534    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    /// Creates a `backend::Conflict` from a `Merge` by dropping `None`
541    /// values. Note that the conversion is lossy: the order of `None` values is
542    /// not preserved when converting back to a `Merge`.
543    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    /// Whether this merge should be recursed into when doing directory walks.
562    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    /// If this merge contains only files or absent entries, returns a merge of
573    /// the `FileId`s`. The executable bits will be ignored. Use
574    /// `Merge::with_new_file_ids()` to produce a new merge with the original
575    /// executable bits preserved.
576    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    /// If this merge contains only files or absent entries, returns a merge of
586    /// the files' executable bits.
587    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    /// If every non-`None` term of a `MergedTreeValue`
597    /// is a `TreeValue::Tree`, this converts it to
598    /// a `Merge<Tree>`, with empty trees instead of
599    /// any `None` terms. Otherwise, returns `None`.
600    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    /// Creates a new merge with the file ids from the given merge. In other
628    /// words, only the executable bits from `self` will be preserved.
629    ///
630    /// The given `file_ids` should have the same shape as `self`. Only the
631    /// `FileId` values may differ.
632    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    /// Give a summary description of the conflict's "removes" and "adds"
649    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        // Non-conflict
775        test_equivalent(
776            (vec![], vec![0]),
777            Merge::from_removes_adds(vec![], vec![Some(0)]),
778        );
779        // Regular 3-way conflict
780        test_equivalent(
781            (vec![0], vec![1, 2]),
782            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
783        );
784        // Modify/delete conflict
785        test_equivalent(
786            (vec![0], vec![1]),
787            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
788        );
789        // Add/add conflict
790        test_equivalent(
791            (vec![], vec![0, 1]),
792            Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
793        );
794        // 5-way conflict
795        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        // 5-way delete/delete conflict
800        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        // Even a trivially resolvable merge is not resolved
813        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        // 1-way merge
822        assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
823        // 3-way merge
824        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        // 5-way merge
830        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        // 1-way merge
921        assert_eq!(c(&[0]).simplify(), c(&[0]));
922        // 3-way merge
923        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        // 5-way merge
929        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        // 1-way merge
987        assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
988        // 3-way merge
989        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        // 5-way merge
996        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        // Check that the `3`s are replaced correctly and that `4` ends up in the
1015        // correct position.
1016        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            // `simplify()` is idempotent
1027            assert_eq!(
1028                merge.simplify().simplify(),
1029                merge.simplify(),
1030                "simplify() not idempotent for {merge:?}"
1031            );
1032            // `resolve_trivial()` is unaffected by `simplify()`
1033            assert_eq!(
1034                merge.simplify().resolve_trivial(),
1035                merge.resolve_trivial(),
1036                "simplify() changed result of resolve_trivial() for {merge:?}"
1037            );
1038        }
1039        // 1-way merge
1040        check_invariants(&[0]);
1041        for i in 0..=1 {
1042            for j in 0..=i + 1 {
1043                // 3-way merge
1044                check_invariants(&[i, 0, j]);
1045                for k in 0..=j + 1 {
1046                    for l in 0..=k + 1 {
1047                        // 5-way merge
1048                        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        // No change if the requested size is smaller
1072        x.pad_to(1, &3);
1073        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1074    }
1075
1076    #[test]
1077    fn test_iter() {
1078        // 1-way merge
1079        assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1080        // 5-way merge
1081        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        // 1-way merge
1090        assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1091        // 5-way merge
1092        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        // 1-way merge
1113        let mut builder: MergeBuilder<i32> = Default::default();
1114        builder.extend([1]);
1115        assert_eq!(builder.build(), c(&[1]));
1116        // 5-way merge
1117        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        // 1-way merge
1129        assert_eq!(c(&[1]).map(increment), c(&[2]));
1130        // 3-way merge
1131        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        // 1-way merge
1144        assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1145        assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1146        // 3-way merge
1147        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        // 1-way merge of 1-way merge
1155        assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1156        // 1-way merge of 3-way merge
1157        assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1158        // 3-way merge of 1-way merges
1159        assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1160        // 3-way merge of 3-way merges
1161        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}