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::hash::Hash;
24use std::iter::zip;
25use std::slice;
26use std::sync::Arc;
27
28use itertools::Itertools;
29use smallvec::smallvec_inline;
30use smallvec::SmallVec;
31
32use crate::backend;
33use crate::backend::BackendResult;
34use crate::backend::FileId;
35use crate::backend::TreeId;
36use crate::backend::TreeValue;
37use crate::content_hash::ContentHash;
38use crate::content_hash::DigestUpdate;
39use crate::repo_path::RepoPath;
40use crate::store::Store;
41use crate::tree::Tree;
42
43/// Attempt to resolve trivial conflicts between the inputs. There must be
44/// an odd number of terms.
45pub fn trivial_merge<T>(values: &[T]) -> Option<&T>
46where
47    T: Eq + Hash,
48{
49    assert!(
50        values.len() % 2 == 1,
51        "trivial_merge() requires an odd number of terms"
52    );
53    // Optimize the common cases of 3-way merge and 1-way (non-)merge
54    if let [add] = values {
55        return Some(add);
56    } else if let [add0, remove, add1] = values {
57        return if add0 == add1 {
58            Some(add0)
59        } else if add0 == remove {
60            Some(add1)
61        } else if add1 == remove {
62            Some(add0)
63        } else {
64            None
65        };
66    }
67
68    // Number of occurrences of each value, with positive indexes counted as +1 and
69    // negative as -1, thereby letting positive and negative terms with the same
70    // value (i.e. key in the map) cancel each other.
71    let mut counts: HashMap<&T, i32> = HashMap::new();
72    for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
73        counts.entry(value).and_modify(|e| *e += n).or_insert(n);
74    }
75
76    // Collect non-zero value. Values with a count of 0 means that they have
77    // cancelled out.
78    counts.retain(|_, count| *count != 0);
79    if counts.len() == 1 {
80        // If there is a single value with a count of 1 left, then that is the result.
81        let (value, count) = counts.into_iter().next().unwrap();
82        assert_eq!(count, 1);
83        Some(value)
84    } else if counts.len() == 2 {
85        // All sides made the same change.
86        // This matches what Git and Mercurial do (in the 3-way case at least), but not
87        // what Darcs does. It means that repeated 3-way merging of multiple trees may
88        // give different results depending on the order of merging.
89        // TODO: Consider removing this special case, making the algorithm more strict,
90        // and maybe add a more lenient version that is used when the user explicitly
91        // asks for conflict resolution.
92        let ((value1, count1), (value2, count2)) = counts.into_iter().next_tuple().unwrap();
93        assert_eq!(count1 + count2, 1);
94        if count1 > 0 {
95            Some(value1)
96        } else {
97            Some(value2)
98        }
99    } else {
100        None
101    }
102}
103
104/// A generic representation of merged values.
105///
106/// There is exactly one more `adds()` than `removes()`. When interpreted as a
107/// series of diffs, the merge's (i+1)-st add is matched with the i-th
108/// remove. The zeroth add is considered a diff from the non-existent state.
109#[derive(PartialEq, Eq, Hash, Clone)]
110pub struct Merge<T> {
111    /// Alternates between positive and negative terms, starting with positive.
112    values: SmallVec<[T; 1]>,
113}
114
115impl<T: Debug> Debug for Merge<T> {
116    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
117        // Format like an enum with two variants to make it less verbose in the common
118        // case of a resolved state.
119        if let Some(value) = self.as_resolved() {
120            f.debug_tuple("Resolved").field(value).finish()
121        } else {
122            f.debug_tuple("Conflicted").field(&self.values).finish()
123        }
124    }
125}
126
127impl<T> Merge<T> {
128    /// Creates a `Merge` from the given values, in which positive and negative
129    /// terms alternate.
130    pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
131        let values = values.into();
132        assert!(values.len() % 2 != 0, "must have an odd number of terms");
133        Merge { values }
134    }
135
136    /// Creates a new merge object from the given removes and adds.
137    pub fn from_removes_adds(
138        removes: impl IntoIterator<Item = T>,
139        adds: impl IntoIterator<Item = T>,
140    ) -> Self {
141        let removes = removes.into_iter();
142        let mut adds = adds.into_iter();
143        let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
144        values.push(adds.next().expect("must have at least one add"));
145        for diff in removes.zip_longest(adds) {
146            let (remove, add) = diff.both().expect("must have one more adds than removes");
147            values.extend([remove, add]);
148        }
149        Merge { values }
150    }
151
152    /// Creates a `Merge` with a single resolved value.
153    pub fn resolved(value: T) -> Self {
154        Merge {
155            values: smallvec_inline![value],
156        }
157    }
158
159    /// Create a `Merge` from a `removes` and `adds`, padding with `None` to
160    /// make sure that there is exactly one more `adds` than `removes`.
161    pub fn from_legacy_form(
162        removes: impl IntoIterator<Item = T>,
163        adds: impl IntoIterator<Item = T>,
164    ) -> Merge<Option<T>> {
165        let removes = removes.into_iter();
166        let mut adds = adds.into_iter().fuse();
167        let mut values = smallvec_inline![adds.next()];
168        for diff in removes.zip_longest(adds) {
169            let (remove, add) = diff.map_any(Some, Some).or_default();
170            values.extend([remove, add]);
171        }
172        Merge { values }
173    }
174
175    /// The removed values, also called negative terms.
176    pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
177        self.values[1..].iter().step_by(2)
178    }
179
180    /// The added values, also called positive terms.
181    pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
182        self.values.iter().step_by(2)
183    }
184
185    /// Returns the zeroth added value, which is guaranteed to exist.
186    pub fn first(&self) -> &T {
187        &self.values[0]
188    }
189
190    /// Returns the `index`-th removed value, which is considered belonging to
191    /// the `index`-th diff pair.
192    pub fn get_remove(&self, index: usize) -> Option<&T> {
193        self.values.get(index * 2 + 1)
194    }
195
196    /// Returns the `index`-th added value, which is considered belonging to the
197    /// `index-1`-th diff pair. The zeroth add is a diff from the non-existent
198    /// state.
199    pub fn get_add(&self, index: usize) -> Option<&T> {
200        self.values.get(index * 2)
201    }
202
203    /// Removes the specified "removed"/"added" values. The removed slots are
204    /// replaced by the last "removed"/"added" values.
205    pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
206        // Swap with the last "added" and "removed" values in order.
207        let add = self.values.swap_remove(add_index * 2);
208        let remove = self.values.swap_remove(remove_index * 2 + 1);
209        (remove, add)
210    }
211
212    /// The number of positive terms in the conflict.
213    pub fn num_sides(&self) -> usize {
214        self.values.len() / 2 + 1
215    }
216
217    /// Whether this merge is resolved. Does not resolve trivial merges.
218    pub fn is_resolved(&self) -> bool {
219        self.values.len() == 1
220    }
221
222    /// Returns the resolved value, if this merge is resolved. Does not
223    /// resolve trivial merges.
224    pub fn as_resolved(&self) -> Option<&T> {
225        if let [value] = &self.values[..] {
226            Some(value)
227        } else {
228            None
229        }
230    }
231
232    /// Returns the resolved value, if this merge is resolved. Otherwise returns
233    /// the merge itself as an `Err`. Does not resolve trivial merges.
234    pub fn into_resolved(mut self) -> Result<T, Merge<T>> {
235        if self.values.len() == 1 {
236            Ok(self.values.pop().unwrap())
237        } else {
238            Err(self)
239        }
240    }
241
242    /// Returns a vector mapping of a value's index in the simplified merge to
243    /// its original index in the unsimplified merge.
244    ///
245    /// The merge is simplified by removing identical values in add and remove
246    /// values.
247    fn get_simplified_mapping(&self) -> Vec<usize>
248    where
249        T: PartialEq,
250    {
251        let unsimplified_len = self.values.len();
252        let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
253
254        let mut add_index = 0;
255        while add_index < simplified_to_original_indices.len() {
256            let add = &self.values[simplified_to_original_indices[add_index]];
257            let mut remove_indices = simplified_to_original_indices
258                .iter()
259                .enumerate()
260                .skip(1)
261                .step_by(2);
262            if let Some((remove_index, _)) = remove_indices
263                .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
264            {
265                // Align the current "add" value to the `remove_index/2`-th diff, then
266                // delete the diff pair.
267                simplified_to_original_indices.swap(remove_index + 1, add_index);
268                simplified_to_original_indices.drain(remove_index..remove_index + 2);
269            } else {
270                add_index += 2;
271            }
272        }
273
274        simplified_to_original_indices
275    }
276
277    /// Simplify the merge by joining diffs like A->B and B->C into A->C.
278    /// Also drops trivial diffs like A->A.
279    pub fn simplify(mut self) -> Self
280    where
281        T: PartialEq + Clone,
282    {
283        let mapping = self.get_simplified_mapping();
284        // Reorder values based on their new indices in the simplified merge.
285        self.values = mapping
286            .iter()
287            .map(|index| self.values[*index].clone())
288            .collect();
289        self
290    }
291
292    /// Updates the merge based on the given simplified merge.
293    pub fn update_from_simplified(mut self, simplified: Merge<T>) -> Self
294    where
295        T: PartialEq,
296    {
297        let mapping = self.get_simplified_mapping();
298        assert_eq!(mapping.len(), simplified.values.len());
299        for (index, value) in mapping.into_iter().zip(simplified.values.into_iter()) {
300            self.values[index] = value;
301        }
302        self
303    }
304
305    /// If this merge can be trivially resolved, returns the value it resolves
306    /// to.
307    pub fn resolve_trivial(&self) -> Option<&T>
308    where
309        T: Eq + Hash,
310    {
311        trivial_merge(&self.values)
312    }
313
314    /// Pads this merge with to the specified number of sides with the specified
315    /// value. No-op if the requested size is not larger than the current size.
316    pub fn pad_to(&mut self, num_sides: usize, value: &T)
317    where
318        T: Clone,
319    {
320        if num_sides <= self.num_sides() {
321            return;
322        }
323        self.values.resize(num_sides * 2 - 1, value.clone());
324    }
325
326    /// Returns a slice containing the terms. The items will alternate between
327    /// positive and negative terms, starting with positive (since there's one
328    /// more of those).
329    pub fn as_slice(&self) -> &[T] {
330        &self.values
331    }
332
333    /// Returns an iterator over references to the terms. The items will
334    /// alternate between positive and negative terms, starting with
335    /// positive (since there's one more of those).
336    pub fn iter(&self) -> slice::Iter<'_, T> {
337        self.values.iter()
338    }
339
340    /// A version of `Merge::iter()` that iterates over mutable references.
341    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
342        self.values.iter_mut()
343    }
344
345    /// Creates a new merge by applying `f` to each remove and add.
346    pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
347        let values = self.values.iter().map(f).collect();
348        Merge { values }
349    }
350
351    /// Creates a new merge by applying `f` to each remove and add, returning
352    /// `None if `f` returns `None` for any of them.
353    pub fn maybe_map<'a, U>(&'a self, f: impl FnMut(&'a T) -> Option<U>) -> Option<Merge<U>> {
354        let values = self.values.iter().map(f).collect::<Option<_>>()?;
355        Some(Merge { values })
356    }
357
358    /// Creates a new merge by applying `f` to each remove and add, returning
359    /// `Err if `f` returns `Err` for any of them.
360    pub fn try_map<'a, U, E>(
361        &'a self,
362        f: impl FnMut(&'a T) -> Result<U, E>,
363    ) -> Result<Merge<U>, E> {
364        let values = self.values.iter().map(f).try_collect()?;
365        Ok(Merge { values })
366    }
367}
368
369/// Helper for consuming items from an iterator and then creating a `Merge`.
370///
371/// By not collecting directly into `Merge`, we can avoid creating invalid
372/// instances of it. If we had `Merge::from_iter()` we would need to allow it to
373/// accept iterators of any length (including 0). We couldn't make it panic on
374/// even lengths because we can get passed such iterators from e.g.
375/// `Option::from_iter()`. By collecting into `MergeBuilder` instead, we move
376/// the checking until after `from_iter()` (to `MergeBuilder::build()`).
377#[derive(Clone, Debug, PartialEq, Eq)]
378pub struct MergeBuilder<T> {
379    values: SmallVec<[T; 1]>,
380}
381
382impl<T> Default for MergeBuilder<T> {
383    fn default() -> Self {
384        Self {
385            values: Default::default(),
386        }
387    }
388}
389
390impl<T> MergeBuilder<T> {
391    /// Requires that exactly one more "adds" than "removes" have been added to
392    /// this builder.
393    pub fn build(self) -> Merge<T> {
394        Merge::from_vec(self.values)
395    }
396}
397
398impl<T> IntoIterator for Merge<T> {
399    type Item = T;
400    type IntoIter = smallvec::IntoIter<[T; 1]>;
401
402    fn into_iter(self) -> Self::IntoIter {
403        self.values.into_iter()
404    }
405}
406
407impl<T> FromIterator<T> for MergeBuilder<T> {
408    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
409        let mut builder = MergeBuilder::default();
410        builder.extend(iter);
411        builder
412    }
413}
414
415impl<T> Extend<T> for MergeBuilder<T> {
416    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
417        self.values.extend(iter);
418    }
419}
420
421impl<T> Merge<Option<T>> {
422    /// Creates a resolved merge with a value of `None`.
423    pub fn absent() -> Self {
424        Self::resolved(None)
425    }
426
427    /// Creates a resolved merge with a value of `Some(value)`.
428    pub fn normal(value: T) -> Self {
429        Self::resolved(Some(value))
430    }
431
432    /// Whether this represents a resolved value of `None`.
433    pub fn is_absent(&self) -> bool {
434        matches!(self.as_resolved(), Some(None))
435    }
436
437    /// The opposite of `is_absent()`.
438    pub fn is_present(&self) -> bool {
439        !self.is_absent()
440    }
441
442    /// Returns the value if this is present and non-conflicting.
443    pub fn as_normal(&self) -> Option<&T> {
444        self.as_resolved()?.as_ref()
445    }
446
447    /// Creates lists of `removes` and `adds` from a `Merge` by dropping
448    /// `None` values. Note that the conversion is lossy: the order of `None`
449    /// values is not preserved when converting back to a `Merge`.
450    pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
451        // Allocate the maximum size assuming there would be few `None`s.
452        let mut removes = Vec::with_capacity(self.values.len() / 2);
453        let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
454        let mut values = self.values.into_iter();
455        adds.extend(values.next().unwrap());
456        while let Some(remove) = values.next() {
457            removes.extend(remove);
458            adds.extend(values.next().unwrap());
459        }
460        (removes, adds)
461    }
462}
463
464impl<T: Clone> Merge<Option<&T>> {
465    /// Creates a new merge by cloning inner `Option<&T>`s.
466    pub fn cloned(&self) -> Merge<Option<T>> {
467        self.map(|value| value.cloned())
468    }
469}
470
471impl<T> Merge<Merge<T>> {
472    /// Flattens a nested merge into a regular merge.
473    ///
474    /// Let's say we have a 3-way merge of 3-way merges like this:
475    ///
476    /// 4 5   7 8
477    ///  3     6
478    ///    1 2
479    ///     0
480    ///
481    /// Flattening that results in this 9-way merge:
482    ///
483    /// 4 5 0 7 8
484    ///  3 2 1 6
485    pub fn flatten(self) -> Merge<T> {
486        let mut outer_values = self.values.into_iter();
487        let mut result = outer_values.next().unwrap();
488        while let Some(mut remove) = outer_values.next() {
489            // Add removes reversed, and with the first element moved last, so we preserve
490            // the diffs
491            remove.values.rotate_left(1);
492            for i in 0..remove.values.len() / 2 {
493                remove.values.swap(i * 2, i * 2 + 1);
494            }
495            result.values.extend(remove.values);
496            let add = outer_values.next().unwrap();
497            result.values.extend(add.values);
498        }
499        result
500    }
501}
502
503impl<T: ContentHash> ContentHash for Merge<T> {
504    fn hash(&self, state: &mut impl DigestUpdate) {
505        self.values.hash(state);
506    }
507}
508
509/// Borrowed `MergedTreeValue`.
510pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
511
512/// The value at a given path in a commit.
513///
514/// It depends on the context whether it can be absent
515/// (`Merge::is_absent()`). For example, when getting the value at a
516/// specific path, it may be, but when iterating over entries in a
517/// tree, it shouldn't be.
518pub type MergedTreeValue = Merge<Option<TreeValue>>;
519
520impl MergedTreeValue {
521    /// Create a `Merge` from a `backend::Conflict`, padding with `None` to
522    /// make sure that there is exactly one more `adds()` than `removes()`.
523    pub fn from_backend_conflict(conflict: backend::Conflict) -> Self {
524        let removes = conflict.removes.into_iter().map(|term| term.value);
525        let adds = conflict.adds.into_iter().map(|term| term.value);
526        Merge::from_legacy_form(removes, adds)
527    }
528
529    /// Creates a `backend::Conflict` from a `Merge` by dropping `None`
530    /// values. Note that the conversion is lossy: the order of `None` values is
531    /// not preserved when converting back to a `Merge`.
532    pub fn into_backend_conflict(self) -> backend::Conflict {
533        let (removes, adds) = self.into_legacy_form();
534        let removes = removes
535            .into_iter()
536            .map(|value| backend::ConflictTerm { value })
537            .collect();
538        let adds = adds
539            .into_iter()
540            .map(|value| backend::ConflictTerm { value })
541            .collect();
542        backend::Conflict { removes, adds }
543    }
544}
545
546impl<T> Merge<Option<T>>
547where
548    T: Borrow<TreeValue>,
549{
550    /// Whether this merge should be recursed into when doing directory walks.
551    pub fn is_tree(&self) -> bool {
552        self.is_present()
553            && self.iter().all(|value| {
554                matches!(
555                    borrow_tree_value(value.as_ref()),
556                    Some(TreeValue::Tree(_)) | None
557                )
558            })
559    }
560
561    /// If this merge contains only files or absent entries, returns a merge of
562    /// the `FileId`s`. The executable bits will be ignored. Use
563    /// `Merge::with_new_file_ids()` to produce a new merge with the original
564    /// executable bits preserved.
565    pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
566        self.maybe_map(|term| match borrow_tree_value(term.as_ref()) {
567            None => Some(None),
568            Some(TreeValue::File { id, executable: _ }) => Some(Some(id.clone())),
569            _ => None,
570        })
571    }
572
573    /// If this merge contains only files or absent entries, returns a merge of
574    /// the files' executable bits.
575    pub fn to_executable_merge(&self) -> Option<Merge<bool>> {
576        self.maybe_map(|term| match borrow_tree_value(term.as_ref()) {
577            None => Some(false),
578            Some(TreeValue::File { id: _, executable }) => Some(*executable),
579            _ => None,
580        })
581    }
582
583    /// If every non-`None` term of a `MergedTreeValue`
584    /// is a `TreeValue::Tree`, this converts it to
585    /// a `Merge<Tree>`, with empty trees instead of
586    /// any `None` terms. Otherwise, returns `None`.
587    pub fn to_tree_merge(
588        &self,
589        store: &Arc<Store>,
590        dir: &RepoPath,
591    ) -> BackendResult<Option<Merge<Tree>>> {
592        let tree_id_merge = self.maybe_map(|term| match borrow_tree_value(term.as_ref()) {
593            None => Some(None),
594            Some(TreeValue::Tree(id)) => Some(Some(id)),
595            Some(_) => None,
596        });
597        if let Some(tree_id_merge) = tree_id_merge {
598            let get_tree = |id: &Option<&TreeId>| -> BackendResult<Tree> {
599                if let Some(id) = id {
600                    store.get_tree(dir.to_owned(), id)
601                } else {
602                    Ok(Tree::empty(store.clone(), dir.to_owned()))
603                }
604            };
605            Ok(Some(tree_id_merge.try_map(get_tree)?))
606        } else {
607            Ok(None)
608        }
609    }
610
611    /// Creates a new merge with the file ids from the given merge. In other
612    /// words, only the executable bits from `self` will be preserved.
613    pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
614        assert_eq!(self.values.len(), file_ids.values.len());
615        let values = zip(self.iter(), file_ids.iter())
616            .map(|(tree_value, file_id)| {
617                if let Some(TreeValue::File { id: _, executable }) =
618                    borrow_tree_value(tree_value.as_ref())
619                {
620                    Some(TreeValue::File {
621                        id: file_id.as_ref().unwrap().clone(),
622                        executable: *executable,
623                    })
624                } else {
625                    assert!(tree_value.is_none());
626                    assert!(file_id.is_none());
627                    None
628                }
629            })
630            .collect();
631        Merge { values }
632    }
633
634    /// Give a summary description of the conflict's "removes" and "adds"
635    pub fn describe(&self) -> String {
636        let mut buf = String::new();
637        writeln!(buf, "Conflict:").unwrap();
638        for term in self.removes().flatten() {
639            writeln!(buf, "  Removing {}", describe_conflict_term(term.borrow())).unwrap();
640        }
641        for term in self.adds().flatten() {
642            writeln!(buf, "  Adding {}", describe_conflict_term(term.borrow())).unwrap();
643        }
644        buf
645    }
646}
647
648fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
649    term.map(|value| value.borrow())
650}
651
652fn describe_conflict_term(value: &TreeValue) -> String {
653    match value {
654        TreeValue::File {
655            id,
656            executable: false,
657        } => {
658            format!("file with id {id}")
659        }
660        TreeValue::File {
661            id,
662            executable: true,
663        } => {
664            format!("executable file with id {id}")
665        }
666        TreeValue::Symlink(id) => {
667            format!("symlink with id {id}")
668        }
669        TreeValue::Tree(id) => {
670            format!("tree with id {id}")
671        }
672        TreeValue::GitSubmodule(id) => {
673            format!("Git submodule with id {id}")
674        }
675        TreeValue::Conflict(id) => {
676            format!("Conflict with id {id}")
677        }
678    }
679}
680
681#[cfg(test)]
682mod tests {
683    use super::*;
684
685    fn c<T: Clone>(terms: &[T]) -> Merge<T> {
686        Merge::from_vec(terms.to_vec())
687    }
688
689    #[test]
690    fn test_trivial_merge() {
691        assert_eq!(trivial_merge(&[0]), Some(&0));
692        assert_eq!(trivial_merge(&[0, 0, 0]), Some(&0));
693        assert_eq!(trivial_merge(&[0, 0, 1]), Some(&1));
694        assert_eq!(trivial_merge(&[0, 1, 0]), Some(&0));
695        assert_eq!(trivial_merge(&[0, 1, 1]), Some(&0));
696        assert_eq!(trivial_merge(&[0, 1, 2]), None);
697        assert_eq!(trivial_merge(&[0, 0, 0, 0, 0]), Some(&0));
698        assert_eq!(trivial_merge(&[0, 0, 0, 0, 1]), Some(&1));
699        assert_eq!(trivial_merge(&[0, 0, 0, 1, 0]), Some(&0));
700        assert_eq!(trivial_merge(&[0, 0, 0, 1, 1]), Some(&0));
701        assert_eq!(trivial_merge(&[0, 0, 0, 1, 2]), None);
702        assert_eq!(trivial_merge(&[0, 0, 1, 0, 0]), Some(&1));
703        assert_eq!(trivial_merge(&[0, 0, 1, 0, 1]), Some(&1));
704        assert_eq!(trivial_merge(&[0, 0, 1, 0, 2]), None);
705        assert_eq!(trivial_merge(&[0, 0, 1, 1, 0]), Some(&0));
706        assert_eq!(trivial_merge(&[0, 0, 1, 1, 1]), Some(&1));
707        assert_eq!(trivial_merge(&[0, 0, 1, 1, 2]), Some(&2));
708        assert_eq!(trivial_merge(&[0, 0, 1, 2, 0]), None);
709        assert_eq!(trivial_merge(&[0, 0, 1, 2, 1]), Some(&1));
710        assert_eq!(trivial_merge(&[0, 0, 1, 2, 2]), Some(&1));
711        assert_eq!(trivial_merge(&[0, 0, 1, 2, 3]), None);
712        assert_eq!(trivial_merge(&[0, 1, 0, 0, 0]), Some(&0));
713        assert_eq!(trivial_merge(&[0, 1, 0, 0, 1]), Some(&0));
714        assert_eq!(trivial_merge(&[0, 1, 0, 0, 2]), None);
715        assert_eq!(trivial_merge(&[0, 1, 0, 1, 0]), Some(&0));
716        assert_eq!(trivial_merge(&[0, 1, 0, 1, 1]), Some(&0));
717        assert_eq!(trivial_merge(&[0, 1, 0, 1, 2]), None);
718        assert_eq!(trivial_merge(&[0, 1, 0, 2, 0]), None);
719        assert_eq!(trivial_merge(&[0, 1, 0, 2, 1]), Some(&0));
720        assert_eq!(trivial_merge(&[0, 1, 0, 2, 2]), Some(&0));
721        assert_eq!(trivial_merge(&[0, 1, 0, 2, 3]), None);
722        assert_eq!(trivial_merge(&[0, 1, 1, 0, 0]), Some(&0));
723        assert_eq!(trivial_merge(&[0, 1, 1, 0, 1]), Some(&1));
724        assert_eq!(trivial_merge(&[0, 1, 1, 0, 2]), Some(&2));
725        assert_eq!(trivial_merge(&[0, 1, 1, 1, 0]), Some(&0));
726        assert_eq!(trivial_merge(&[0, 1, 1, 1, 1]), Some(&0));
727        assert_eq!(trivial_merge(&[0, 1, 1, 1, 2]), None);
728        assert_eq!(trivial_merge(&[0, 1, 1, 2, 0]), Some(&0));
729        assert_eq!(trivial_merge(&[0, 1, 1, 2, 1]), None);
730        assert_eq!(trivial_merge(&[0, 1, 1, 2, 2]), Some(&0));
731        assert_eq!(trivial_merge(&[0, 1, 1, 2, 3]), None);
732        assert_eq!(trivial_merge(&[0, 1, 2, 0, 0]), None);
733        assert_eq!(trivial_merge(&[0, 1, 2, 0, 1]), Some(&2));
734        assert_eq!(trivial_merge(&[0, 1, 2, 0, 2]), Some(&2));
735        assert_eq!(trivial_merge(&[0, 1, 2, 0, 3]), None);
736        assert_eq!(trivial_merge(&[0, 1, 2, 1, 0]), None);
737        assert_eq!(trivial_merge(&[0, 1, 2, 1, 1]), None);
738        assert_eq!(trivial_merge(&[0, 1, 2, 1, 2]), None);
739        assert_eq!(trivial_merge(&[0, 1, 2, 1, 3]), None);
740        assert_eq!(trivial_merge(&[0, 1, 2, 2, 0]), Some(&0));
741        assert_eq!(trivial_merge(&[0, 1, 2, 2, 1]), Some(&0));
742        assert_eq!(trivial_merge(&[0, 1, 2, 2, 2]), None);
743        assert_eq!(trivial_merge(&[0, 1, 2, 2, 3]), None);
744        assert_eq!(trivial_merge(&[0, 1, 2, 3, 0]), None);
745        assert_eq!(trivial_merge(&[0, 1, 2, 3, 1]), None);
746        assert_eq!(trivial_merge(&[0, 1, 2, 3, 2]), None);
747        assert_eq!(trivial_merge(&[0, 1, 2, 3, 3]), None);
748        assert_eq!(trivial_merge(&[0, 1, 2, 3, 4]), None);
749    }
750
751    #[test]
752    fn test_legacy_form_conversion() {
753        fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
754        where
755            T: Clone + PartialEq + std::fmt::Debug,
756        {
757            assert_eq!(merge.clone().into_legacy_form(), legacy_form);
758            assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
759        }
760        // Non-conflict
761        test_equivalent(
762            (vec![], vec![0]),
763            Merge::from_removes_adds(vec![], vec![Some(0)]),
764        );
765        // Regular 3-way conflict
766        test_equivalent(
767            (vec![0], vec![1, 2]),
768            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
769        );
770        // Modify/delete conflict
771        test_equivalent(
772            (vec![0], vec![1]),
773            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
774        );
775        // Add/add conflict
776        test_equivalent(
777            (vec![], vec![0, 1]),
778            Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
779        );
780        // 5-way conflict
781        test_equivalent(
782            (vec![0, 1], vec![2, 3, 4]),
783            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
784        );
785        // 5-way delete/delete conflict
786        test_equivalent(
787            (vec![0, 1], vec![]),
788            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
789        );
790    }
791
792    #[test]
793    fn test_as_resolved() {
794        assert_eq!(
795            Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
796            Some(&0)
797        );
798        // Even a trivially resolvable merge is not resolved
799        assert_eq!(
800            Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
801            None
802        );
803    }
804
805    #[test]
806    fn test_get_simplified_mapping() {
807        // 1-way merge
808        assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
809        // 3-way merge
810        assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
811        assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
812        assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
813        assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
814        assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
815        // 5-way merge
816        assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
817        assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
818        assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
819        assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
820        assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
821        assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
822        assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
823        assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
824        assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
825        assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
826        assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
827        assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
828        assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
829        assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
830        assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
831        assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
832        assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
833        assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
834        assert_eq!(
835            c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
836            vec![0, 1, 2, 3, 4]
837        );
838        assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
839        assert_eq!(
840            c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
841            vec![0, 1, 2, 3, 4]
842        );
843        assert_eq!(
844            c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
845            vec![0, 1, 2, 3, 4]
846        );
847        assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
848        assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
849        assert_eq!(
850            c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
851            vec![0, 1, 2, 3, 4]
852        );
853        assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
854        assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
855        assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
856        assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
857        assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
858        assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
859        assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
860        assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
861        assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
862        assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
863        assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
864        assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
865        assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
866        assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
867        assert_eq!(
868            c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
869            vec![0, 1, 2, 3, 4]
870        );
871        assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
872        assert_eq!(
873            c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
874            vec![0, 1, 2, 3, 4]
875        );
876        assert_eq!(
877            c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
878            vec![0, 1, 2, 3, 4]
879        );
880        assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
881        assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
882        assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
883        assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
884        assert_eq!(
885            c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
886            vec![0, 1, 2, 3, 4]
887        );
888        assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
889        assert_eq!(
890            c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
891            vec![0, 1, 2, 3, 4]
892        );
893        assert_eq!(
894            c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
895            vec![0, 3, 4, 5, 2]
896        );
897        assert_eq!(
898            c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
899            vec![0, 1, 2, 3, 4]
900        );
901        assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
902    }
903
904    #[test]
905    fn test_simplify() {
906        // 1-way merge
907        assert_eq!(c(&[0]).simplify(), c(&[0]));
908        // 3-way merge
909        assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
910        assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
911        assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
912        assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
913        assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
914        // 5-way merge
915        assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
916        assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
917        assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
918        assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
919        assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
920        assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
921        assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
922        assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
923        assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
924        assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
925        assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
926        assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
927        assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
928        assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
929        assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
930        assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
931        assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
932        assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
933        assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
934        assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
935        assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
936        assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
937        assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
938        assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
939        assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
940        assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
941        assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
942        assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
943        assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
944        assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
945        assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
946        assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
947        assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
948        assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
949        assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
950        assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
951        assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
952        assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
953        assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
954        assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
955        assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
956        assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
957        assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
958        assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
959        assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
960        assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
961        assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
962        assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
963        assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
964        assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
965        assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
966        assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
967        assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
968    }
969
970    #[test]
971    fn test_update_from_simplified() {
972        // 1-way merge
973        assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
974        // 3-way merge
975        assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
976        assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
977        assert_eq!(
978            c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
979            c(&[2, 1, 3])
980        );
981        // 5-way merge
982        assert_eq!(
983            c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
984            c(&[0, 0, 0, 0, 1])
985        );
986        assert_eq!(
987            c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
988            c(&[0, 0, 2, 3, 1])
989        );
990        assert_eq!(
991            c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
992            c(&[0, 3, 1, 0, 2])
993        );
994        assert_eq!(
995            c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
996            c(&[3, 1, 4, 2, 5])
997        );
998
999        assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1000        // Check that the `3`s are replaced correctly and that `4` ends up in the
1001        // correct position.
1002        assert_eq!(
1003            c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1004            c(&[0, 0, 10, 1, 11, 2, 4])
1005        );
1006    }
1007
1008    #[test]
1009    fn test_merge_invariants() {
1010        fn check_invariants(terms: &[u32]) {
1011            let merge = Merge::from_vec(terms.to_vec());
1012            // `simplify()` is idempotent
1013            assert_eq!(
1014                merge.clone().simplify().simplify(),
1015                merge.clone().simplify(),
1016                "simplify() not idempotent for {merge:?}"
1017            );
1018            // `resolve_trivial()` is unaffected by `simplify()`
1019            assert_eq!(
1020                merge.clone().simplify().resolve_trivial(),
1021                merge.resolve_trivial(),
1022                "simplify() changed result of resolve_trivial() for {merge:?}"
1023            );
1024        }
1025        // 1-way merge
1026        check_invariants(&[0]);
1027        for i in 0..=1 {
1028            for j in 0..=i + 1 {
1029                // 3-way merge
1030                check_invariants(&[i, 0, j]);
1031                for k in 0..=j + 1 {
1032                    for l in 0..=k + 1 {
1033                        // 5-way merge
1034                        check_invariants(&[0, i, j, k, l]);
1035                    }
1036                }
1037            }
1038        }
1039    }
1040
1041    #[test]
1042    fn test_swap_remove() {
1043        let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1044        assert_eq!(x.swap_remove(0, 1), (1, 2));
1045        assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1046        assert_eq!(x.swap_remove(1, 0), (3, 0));
1047        assert_eq!(x, c(&[4, 5, 6]));
1048        assert_eq!(x.swap_remove(0, 1), (5, 6));
1049        assert_eq!(x, c(&[4]));
1050    }
1051
1052    #[test]
1053    fn test_pad_to() {
1054        let mut x = c(&[1]);
1055        x.pad_to(3, &2);
1056        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1057        // No change if the requested size is smaller
1058        x.pad_to(1, &3);
1059        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1060    }
1061
1062    #[test]
1063    fn test_iter() {
1064        // 1-way merge
1065        assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1066        // 5-way merge
1067        assert_eq!(
1068            c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1069            vec![&1, &2, &3, &4, &5]
1070        );
1071    }
1072
1073    #[test]
1074    fn test_from_iter() {
1075        // 1-way merge
1076        assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1077        // 5-way merge
1078        assert_eq!(
1079            MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1080            c(&[1, 2, 3, 4, 5])
1081        );
1082    }
1083
1084    #[test]
1085    #[should_panic]
1086    fn test_from_iter_empty() {
1087        MergeBuilder::from_iter([1; 0]).build();
1088    }
1089
1090    #[test]
1091    #[should_panic]
1092    fn test_from_iter_even() {
1093        MergeBuilder::from_iter([1, 2]).build();
1094    }
1095
1096    #[test]
1097    fn test_extend() {
1098        // 1-way merge
1099        let mut builder: MergeBuilder<i32> = Default::default();
1100        builder.extend([1]);
1101        assert_eq!(builder.build(), c(&[1]));
1102        // 5-way merge
1103        let mut builder: MergeBuilder<i32> = Default::default();
1104        builder.extend([1, 2]);
1105        builder.extend([3, 4, 5]);
1106        assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1107    }
1108
1109    #[test]
1110    fn test_map() {
1111        fn increment(i: &i32) -> i32 {
1112            i + 1
1113        }
1114        // 1-way merge
1115        assert_eq!(c(&[1]).map(increment), c(&[2]));
1116        // 3-way merge
1117        assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1118    }
1119
1120    #[test]
1121    fn test_maybe_map() {
1122        fn sqrt(i: &i32) -> Option<i32> {
1123            if *i >= 0 {
1124                Some((*i as f64).sqrt() as i32)
1125            } else {
1126                None
1127            }
1128        }
1129        // 1-way merge
1130        assert_eq!(c(&[1]).maybe_map(sqrt), Some(c(&[1])));
1131        assert_eq!(c(&[-1]).maybe_map(sqrt), None);
1132        // 3-way merge
1133        assert_eq!(c(&[1, 4, 9]).maybe_map(sqrt), Some(c(&[1, 2, 3])));
1134        assert_eq!(c(&[-1, 4, 9]).maybe_map(sqrt), None);
1135        assert_eq!(c(&[1, -4, 9]).maybe_map(sqrt), None);
1136    }
1137
1138    #[test]
1139    fn test_try_map() {
1140        fn sqrt(i: &i32) -> Result<i32, ()> {
1141            if *i >= 0 {
1142                Ok((*i as f64).sqrt() as i32)
1143            } else {
1144                Err(())
1145            }
1146        }
1147        // 1-way merge
1148        assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1149        assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1150        // 3-way merge
1151        assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1152        assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1153        assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1154    }
1155
1156    #[test]
1157    fn test_flatten() {
1158        // 1-way merge of 1-way merge
1159        assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1160        // 1-way merge of 3-way merge
1161        assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1162        // 3-way merge of 1-way merges
1163        assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1164        // 3-way merge of 3-way merges
1165        assert_eq!(
1166            c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1167            c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1168        );
1169    }
1170}