Skip to main content

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