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    /// The removed values, also called negative terms.
261    pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
262        self.values[1..].iter().step_by(2)
263    }
264
265    /// The added values, also called positive terms.
266    pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
267        self.values.iter().step_by(2)
268    }
269
270    /// Return the removed values and added values and take the ownership.
271    pub fn into_removes_adds(
272        self,
273    ) -> (
274        impl ExactSizeIterator<Item = T>,
275        impl ExactSizeIterator<Item = T>,
276    ) {
277        let (removes, adds): (Vec<_>, Vec<_>) = self
278            .values
279            .into_iter()
280            .enumerate()
281            .partition(|(n, _)| *n % 2 == 1);
282        (
283            removes.into_iter().map(|(_, item)| item),
284            adds.into_iter().map(|(_, item)| item),
285        )
286    }
287
288    /// Returns the zeroth added value, which is guaranteed to exist.
289    pub fn first(&self) -> &T {
290        &self.values[0]
291    }
292
293    /// Returns the `index`-th removed value, which is considered belonging to
294    /// the `index`-th diff pair.
295    pub fn get_remove(&self, index: usize) -> Option<&T> {
296        self.values.get(index * 2 + 1)
297    }
298
299    /// Returns the `index`-th added value, which is considered belonging to the
300    /// `index-1`-th diff pair. The zeroth add is a diff from the non-existent
301    /// state.
302    pub fn get_add(&self, index: usize) -> Option<&T> {
303        self.values.get(index * 2)
304    }
305
306    /// Removes the specified "removed"/"added" values. The removed slots are
307    /// replaced by the last "removed"/"added" values.
308    pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
309        // Swap with the last "added" and "removed" values in order.
310        let add = self.values.swap_remove(add_index * 2);
311        let remove = self.values.swap_remove(remove_index * 2 + 1);
312        (remove, add)
313    }
314
315    /// The number of positive terms in the conflict.
316    pub fn num_sides(&self) -> usize {
317        self.values.len() / 2 + 1
318    }
319
320    /// Whether this merge is resolved. Does not resolve trivial merges.
321    pub fn is_resolved(&self) -> bool {
322        self.values.len() == 1
323    }
324
325    /// Returns the resolved value, if this merge is resolved. Does not
326    /// resolve trivial merges.
327    pub fn as_resolved(&self) -> Option<&T> {
328        if let [value] = &self.values[..] {
329            Some(value)
330        } else {
331            None
332        }
333    }
334
335    /// Returns the resolved value, if this merge is resolved. Otherwise returns
336    /// the merge itself as an `Err`. Does not resolve trivial merges.
337    pub fn into_resolved(mut self) -> Result<T, Self> {
338        if self.values.len() == 1 {
339            Ok(self.values.pop().unwrap())
340        } else {
341            Err(self)
342        }
343    }
344
345    /// Returns a vector mapping of a value's index in the simplified merge to
346    /// its original index in the unsimplified merge.
347    ///
348    /// The merge is simplified by removing identical values in add and remove
349    /// values.
350    fn get_simplified_mapping(&self) -> Vec<usize>
351    where
352        T: PartialEq,
353    {
354        let unsimplified_len = self.values.len();
355        let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
356
357        let mut add_index = 0;
358        while add_index < simplified_to_original_indices.len() {
359            let add = &self.values[simplified_to_original_indices[add_index]];
360            let mut remove_indices = simplified_to_original_indices
361                .iter()
362                .enumerate()
363                .skip(1)
364                .step_by(2);
365            if let Some((remove_index, _)) = remove_indices
366                .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
367            {
368                // Align the current "add" value to the `remove_index/2`-th diff, then
369                // delete the diff pair.
370                simplified_to_original_indices.swap(remove_index + 1, add_index);
371                simplified_to_original_indices.drain(remove_index..remove_index + 2);
372            } else {
373                add_index += 2;
374            }
375        }
376
377        simplified_to_original_indices
378    }
379
380    /// Apply the mapping returned by [`Self::get_simplified_mapping`].
381    #[must_use]
382    fn apply_simplified_mapping(&self, mapping: &[usize]) -> Self
383    where
384        T: Clone,
385    {
386        // Reorder values based on their new indices in the simplified merge.
387        let values = mapping
388            .iter()
389            .map(|index| self.values[*index].clone())
390            .collect();
391        Self { values }
392    }
393
394    /// Simplify the merge by joining diffs like A->B and B->C into A->C.
395    /// Also drops trivial diffs like A->A.
396    #[must_use]
397    pub fn simplify(&self) -> Self
398    where
399        T: PartialEq + Clone,
400    {
401        let mapping = self.get_simplified_mapping();
402        self.apply_simplified_mapping(&mapping)
403    }
404
405    /// Simplify the merge, using a function to choose which values to compare.
406    #[must_use]
407    pub fn simplify_by<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Self
408    where
409        T: Clone,
410        U: PartialEq,
411    {
412        let mapping = self.map(f).get_simplified_mapping();
413        self.apply_simplified_mapping(&mapping)
414    }
415
416    /// Updates the merge based on the given simplified merge.
417    pub fn update_from_simplified(mut self, simplified: Self) -> Self
418    where
419        T: PartialEq,
420    {
421        let mapping = self.get_simplified_mapping();
422        assert_eq!(mapping.len(), simplified.values.len());
423        for (index, value) in mapping.into_iter().zip(simplified.values) {
424            self.values[index] = value;
425        }
426        self
427    }
428
429    /// If this merge can be trivially resolved, returns the value it resolves
430    /// to.
431    pub fn resolve_trivial(&self, same_change: SameChange) -> Option<&T>
432    where
433        T: Eq + Hash,
434    {
435        trivial_merge(&self.values, same_change)
436    }
437
438    /// Pads this merge with to the specified number of sides with the specified
439    /// value. No-op if the requested size is not larger than the current size.
440    pub fn pad_to(&mut self, num_sides: usize, value: &T)
441    where
442        T: Clone,
443    {
444        if num_sides <= self.num_sides() {
445            return;
446        }
447        self.values.resize(num_sides * 2 - 1, value.clone());
448    }
449
450    /// Returns a slice containing the terms. The items will alternate between
451    /// positive and negative terms, starting with positive (since there's one
452    /// more of those).
453    pub fn as_slice(&self) -> &[T] {
454        &self.values
455    }
456
457    /// Returns an iterator over references to the terms. The items will
458    /// alternate between positive and negative terms, starting with
459    /// positive (since there's one more of those).
460    pub fn iter(&self) -> slice::Iter<'_, T> {
461        self.values.iter()
462    }
463
464    /// A version of `Merge::iter()` that iterates over mutable references.
465    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
466        self.values.iter_mut()
467    }
468
469    /// Creates a new merge by applying `f` to each remove and add.
470    pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
471        let values = self.values.iter().map(f).collect();
472        Merge { values }
473    }
474
475    /// Creates a new merge by applying `f` to each remove and add, consuming
476    /// `self`.
477    pub fn into_map<U>(self, f: impl FnMut(T) -> U) -> Merge<U> {
478        let values = self.values.into_iter().map(f).collect();
479        Merge { values }
480    }
481
482    /// Creates a new merge by applying `f` to each remove and add, returning
483    /// `Err` if `f` returns `Err` for any of them.
484    pub fn try_map<'a, U, E>(
485        &'a self,
486        f: impl FnMut(&'a T) -> Result<U, E>,
487    ) -> Result<Merge<U>, E> {
488        let values = self.values.iter().map(f).try_collect()?;
489        Ok(Merge { values })
490    }
491
492    /// Creates a new merge by applying the async function `f` to each remove
493    /// and add, running them concurrently, and returning `Err` if `f`
494    /// returns `Err` for any of them.
495    pub async fn try_map_async<'a, F, U, E>(
496        &'a self,
497        f: impl FnMut(&'a T) -> F,
498    ) -> Result<Merge<U>, E>
499    where
500        F: Future<Output = Result<U, E>>,
501    {
502        let values = try_join_all(self.values.iter().map(f)).await?;
503        Ok(Merge {
504            values: values.into(),
505        })
506    }
507
508    /// Converts a `&Merge<T>` into a `Merge<&T>`.
509    pub fn as_ref(&self) -> Merge<&T> {
510        let values = self.values.iter().collect();
511        Merge { values }
512    }
513
514    /// Zip two merges which have the same number of terms. Panics if the merges
515    /// don't have the same number of terms.
516    pub fn zip<U>(self, other: Merge<U>) -> Merge<(T, U)> {
517        assert_eq!(self.values.len(), other.values.len());
518        let values = self.values.into_iter().zip(other.values).collect();
519        Merge { values }
520    }
521}
522
523impl<T, U> Merge<(T, U)> {
524    /// Unzips a merge of pairs into a pair of merges.
525    pub fn unzip(self) -> (Merge<T>, Merge<U>) {
526        let (left, right) = self.values.into_iter().unzip();
527        (Merge { values: left }, Merge { values: right })
528    }
529}
530
531impl<T> Merge<&'_ T> {
532    /// Convert a `Merge<&T>` into a `Merge<T>` by cloning each term.
533    pub fn cloned(&self) -> Merge<T>
534    where
535        T: Clone,
536    {
537        self.map(|&term| term.clone())
538    }
539}
540
541/// Helper for consuming items from an iterator and then creating a `Merge`.
542///
543/// By not collecting directly into `Merge`, we can avoid creating invalid
544/// instances of it. If we had `Merge::from_iter()` we would need to allow it to
545/// accept iterators of any length (including 0). We couldn't make it panic on
546/// even lengths because we can get passed such iterators from e.g.
547/// `Option::from_iter()`. By collecting into `MergeBuilder` instead, we move
548/// the checking until after `from_iter()` (to `MergeBuilder::build()`).
549#[derive(Clone, Debug, PartialEq, Eq)]
550pub struct MergeBuilder<T> {
551    values: SmallVec<[T; 1]>,
552}
553
554impl<T> Default for MergeBuilder<T> {
555    fn default() -> Self {
556        Self {
557            values: Default::default(),
558        }
559    }
560}
561
562impl<T> MergeBuilder<T> {
563    /// Requires that exactly one more "adds" than "removes" have been added to
564    /// this builder.
565    pub fn build(self) -> Merge<T> {
566        Merge::from_vec(self.values)
567    }
568}
569
570impl<T> IntoIterator for Merge<T> {
571    type Item = T;
572    type IntoIter = smallvec::IntoIter<[T; 1]>;
573
574    fn into_iter(self) -> Self::IntoIter {
575        self.values.into_iter()
576    }
577}
578
579impl<'a, T> IntoIterator for &'a Merge<T> {
580    type Item = &'a T;
581    type IntoIter = slice::Iter<'a, T>;
582
583    fn into_iter(self) -> Self::IntoIter {
584        self.iter()
585    }
586}
587
588impl<'a, T> IntoIterator for &'a mut Merge<T> {
589    type Item = &'a mut T;
590    type IntoIter = slice::IterMut<'a, T>;
591
592    fn into_iter(self) -> Self::IntoIter {
593        self.iter_mut()
594    }
595}
596
597impl<T> FromIterator<T> for MergeBuilder<T> {
598    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
599        let mut builder = Self::default();
600        builder.extend(iter);
601        builder
602    }
603}
604
605impl<T> Extend<T> for MergeBuilder<T> {
606    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
607        self.values.extend(iter);
608    }
609}
610
611impl<T> Merge<Option<T>> {
612    /// Creates a resolved merge with a value of `None`.
613    pub const fn absent() -> Self {
614        Self::resolved(None)
615    }
616
617    /// Creates a resolved merge with a value of `Some(value)`.
618    pub fn normal(value: T) -> Self {
619        Self::resolved(Some(value))
620    }
621
622    /// Create a `Merge` from a `removes` and `adds`, padding with `None` to
623    /// make sure that there is exactly one more `adds` than `removes`.
624    pub fn from_legacy_form(
625        removes: impl IntoIterator<Item = T>,
626        adds: impl IntoIterator<Item = T>,
627    ) -> Self {
628        let removes = removes.into_iter();
629        let mut adds = adds.into_iter().fuse();
630        let mut values = smallvec_inline![adds.next()];
631        for diff in removes.zip_longest(adds) {
632            let (remove, add) = diff.map_any(Some, Some).or_default();
633            values.extend([remove, add]);
634        }
635        Self { values }
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    /// The removed values, excluding `None` terms.
654    pub fn present_removes(&self) -> impl Iterator<Item = &T> {
655        self.removes().flatten()
656    }
657
658    /// The added values, excluding `None` terms.
659    pub fn present_adds(&self) -> impl Iterator<Item = &T> {
660        self.adds().flatten()
661    }
662
663    /// Creates lists of `removes` and `adds` from a `Merge` by dropping
664    /// `None` values. Note that the conversion is lossy: the order of `None`
665    /// values is not preserved when converting back to a `Merge`.
666    pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
667        // Allocate the maximum size assuming there would be few `None`s.
668        let mut removes = Vec::with_capacity(self.values.len() / 2);
669        let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
670        let mut values = self.values.into_iter();
671        adds.extend(values.next().unwrap());
672        while let Some(remove) = values.next() {
673            removes.extend(remove);
674            adds.extend(values.next().unwrap());
675        }
676        (removes, adds)
677    }
678}
679
680impl<T: Clone> Merge<Option<&T>> {
681    /// Creates a new merge by cloning inner `Option<&T>`s.
682    pub fn cloned(&self) -> Merge<Option<T>> {
683        self.map(|value| value.cloned())
684    }
685}
686
687impl<T> Merge<Merge<T>> {
688    /// Flattens a nested merge into a regular merge.
689    ///
690    /// Let's say we have a 3-way merge of 3-way merges like this:
691    ///
692    /// ```text
693    /// 4 5   7 8
694    ///  3     6
695    ///    1 2
696    ///     0
697    /// ```
698    ///
699    /// Flattening that results in this 9-way merge:
700    ///
701    /// ```text
702    /// 4 5 0 7 8
703    ///  3 2 1 6
704    /// ```
705    pub fn flatten(self) -> Merge<T> {
706        let mut outer_values = self.values.into_iter();
707        let mut result = outer_values.next().unwrap();
708        while let Some(mut remove) = outer_values.next() {
709            // Add removes reversed, and with the first element moved last, so we preserve
710            // the diffs
711            remove.values.rotate_left(1);
712            for i in 0..remove.values.len() / 2 {
713                remove.values.swap(i * 2, i * 2 + 1);
714            }
715            result.values.extend(remove.values);
716            let add = outer_values.next().unwrap();
717            result.values.extend(add.values);
718        }
719        result
720    }
721}
722
723#[cfg(test)]
724mod tests {
725    use test_case::test_case;
726
727    use super::*;
728
729    #[test]
730    fn test_diff_map() {
731        let diff = Diff::new(1, 2);
732        assert_eq!(diff.map(|x| x + 2), Diff::new(3, 4));
733    }
734
735    #[test]
736    fn test_diff_zip() {
737        let diff1 = Diff::new(1, 2);
738        let diff2 = Diff::new(3, 4);
739        assert_eq!(diff1.zip(diff2), Diff::new((1, 3), (2, 4)));
740    }
741
742    #[test]
743    fn test_diff_invert() {
744        let diff = Diff::new(1, 2);
745        assert_eq!(diff.invert(), Diff::new(2, 1));
746    }
747
748    #[test]
749    fn test_diff_as_ref() {
750        let diff = Diff::new(1, 2);
751        assert_eq!(diff.as_ref(), Diff::new(&1, &2));
752    }
753
754    #[test]
755    fn test_diff_into_array() {
756        let diff = Diff::new(1, 2);
757        assert_eq!(diff.into_array(), [1, 2]);
758    }
759
760    #[test]
761    fn test_merge_from_diffs() {
762        assert_eq!(Merge::from_diffs(1, []), Merge::resolved(1));
763        assert_eq!(
764            Merge::from_diffs(1, [Diff::new(2, 3)]),
765            Merge::from_vec(vec![1, 2, 3])
766        );
767        assert_eq!(
768            Merge::from_diffs(1, [Diff::new(2, 3), Diff::new(4, 5)]),
769            Merge::from_vec(vec![1, 2, 3, 4, 5])
770        );
771    }
772
773    fn c<T: Clone>(terms: &[T]) -> Merge<T> {
774        Merge::from_vec(terms.to_vec())
775    }
776
777    #[test_case(SameChange::Keep)]
778    #[test_case(SameChange::Accept)]
779    fn test_trivial_merge(same_change: SameChange) {
780        let accept_same_change = same_change == SameChange::Accept;
781        let merge = |values| trivial_merge(values, same_change);
782        assert_eq!(merge(&[0]), Some(&0));
783        assert_eq!(merge(&[0, 0, 0]), Some(&0));
784        assert_eq!(merge(&[0, 0, 1]), Some(&1));
785        assert_eq!(merge(&[0, 1, 0]), accept_same_change.then_some(&0));
786        assert_eq!(merge(&[0, 1, 1]), Some(&0));
787        assert_eq!(merge(&[0, 1, 2]), None);
788        assert_eq!(merge(&[0, 0, 0, 0, 0]), Some(&0));
789        assert_eq!(merge(&[0, 0, 0, 0, 1]), Some(&1));
790        assert_eq!(merge(&[0, 0, 0, 1, 0]), accept_same_change.then_some(&0));
791        assert_eq!(merge(&[0, 0, 0, 1, 1]), Some(&0));
792        assert_eq!(merge(&[0, 0, 0, 1, 2]), None);
793        assert_eq!(merge(&[0, 0, 1, 0, 0]), Some(&1));
794        assert_eq!(merge(&[0, 0, 1, 0, 1]), accept_same_change.then_some(&1));
795        assert_eq!(merge(&[0, 0, 1, 0, 2]), None);
796        assert_eq!(merge(&[0, 0, 1, 1, 0]), Some(&0));
797        assert_eq!(merge(&[0, 0, 1, 1, 1]), Some(&1));
798        assert_eq!(merge(&[0, 0, 1, 1, 2]), Some(&2));
799        assert_eq!(merge(&[0, 0, 1, 2, 0]), None);
800        assert_eq!(merge(&[0, 0, 1, 2, 1]), accept_same_change.then_some(&1));
801        assert_eq!(merge(&[0, 0, 1, 2, 2]), Some(&1));
802        assert_eq!(merge(&[0, 0, 1, 2, 3]), None);
803        assert_eq!(merge(&[0, 1, 0, 0, 0]), accept_same_change.then_some(&0));
804        assert_eq!(merge(&[0, 1, 0, 0, 1]), Some(&0));
805        assert_eq!(merge(&[0, 1, 0, 0, 2]), None);
806        assert_eq!(merge(&[0, 1, 0, 1, 0]), accept_same_change.then_some(&0));
807        assert_eq!(merge(&[0, 1, 0, 1, 1]), accept_same_change.then_some(&0));
808        assert_eq!(merge(&[0, 1, 0, 1, 2]), None);
809        assert_eq!(merge(&[0, 1, 0, 2, 0]), None);
810        assert_eq!(merge(&[0, 1, 0, 2, 1]), accept_same_change.then_some(&0));
811        assert_eq!(merge(&[0, 1, 0, 2, 2]), accept_same_change.then_some(&0));
812        assert_eq!(merge(&[0, 1, 0, 2, 3]), None);
813        assert_eq!(merge(&[0, 1, 1, 0, 0]), Some(&0));
814        assert_eq!(merge(&[0, 1, 1, 0, 1]), Some(&1));
815        assert_eq!(merge(&[0, 1, 1, 0, 2]), Some(&2));
816        assert_eq!(merge(&[0, 1, 1, 1, 0]), accept_same_change.then_some(&0));
817        assert_eq!(merge(&[0, 1, 1, 1, 1]), Some(&0));
818        assert_eq!(merge(&[0, 1, 1, 1, 2]), None);
819        assert_eq!(merge(&[0, 1, 1, 2, 0]), accept_same_change.then_some(&0));
820        assert_eq!(merge(&[0, 1, 1, 2, 1]), None);
821        assert_eq!(merge(&[0, 1, 1, 2, 2]), Some(&0));
822        assert_eq!(merge(&[0, 1, 1, 2, 3]), None);
823        assert_eq!(merge(&[0, 1, 2, 0, 0]), None);
824        assert_eq!(merge(&[0, 1, 2, 0, 1]), Some(&2));
825        assert_eq!(merge(&[0, 1, 2, 0, 2]), accept_same_change.then_some(&2));
826        assert_eq!(merge(&[0, 1, 2, 0, 3]), None);
827        assert_eq!(merge(&[0, 1, 2, 1, 0]), None);
828        assert_eq!(merge(&[0, 1, 2, 1, 1]), None);
829        assert_eq!(merge(&[0, 1, 2, 1, 2]), None);
830        assert_eq!(merge(&[0, 1, 2, 1, 3]), None);
831        assert_eq!(merge(&[0, 1, 2, 2, 0]), accept_same_change.then_some(&0));
832        assert_eq!(merge(&[0, 1, 2, 2, 1]), Some(&0));
833        assert_eq!(merge(&[0, 1, 2, 2, 2]), None);
834        assert_eq!(merge(&[0, 1, 2, 2, 3]), None);
835        assert_eq!(merge(&[0, 1, 2, 3, 0]), None);
836        assert_eq!(merge(&[0, 1, 2, 3, 1]), None);
837        assert_eq!(merge(&[0, 1, 2, 3, 2]), None);
838        assert_eq!(merge(&[0, 1, 2, 3, 3]), None);
839        assert_eq!(merge(&[0, 1, 2, 3, 4]), None);
840    }
841
842    #[test]
843    fn test_legacy_form_conversion() {
844        fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
845        where
846            T: Clone + PartialEq + std::fmt::Debug,
847        {
848            assert_eq!(merge.clone().into_legacy_form(), legacy_form);
849            assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
850        }
851        // Non-conflict
852        test_equivalent(
853            (vec![], vec![0]),
854            Merge::from_removes_adds(vec![], vec![Some(0)]),
855        );
856        // Regular 3-way conflict
857        test_equivalent(
858            (vec![0], vec![1, 2]),
859            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
860        );
861        // Modify/delete conflict
862        test_equivalent(
863            (vec![0], vec![1]),
864            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
865        );
866        // Add/add conflict
867        test_equivalent(
868            (vec![], vec![0, 1]),
869            Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
870        );
871        // 5-way conflict
872        test_equivalent(
873            (vec![0, 1], vec![2, 3, 4]),
874            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
875        );
876        // 5-way delete/delete conflict
877        test_equivalent(
878            (vec![0, 1], vec![]),
879            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
880        );
881    }
882
883    #[test]
884    fn test_as_resolved() {
885        assert_eq!(
886            Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
887            Some(&0)
888        );
889        // Even a trivially resolvable merge is not resolved
890        assert_eq!(
891            Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
892            None
893        );
894    }
895
896    #[test]
897    fn test_get_simplified_mapping() {
898        // 1-way merge
899        assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
900        // 3-way merge
901        assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
902        assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
903        assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
904        assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
905        assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
906        // 5-way merge
907        assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
908        assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
909        assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
910        assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
911        assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
912        assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
913        assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
914        assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
915        assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
916        assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
917        assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
918        assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
919        assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
920        assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
921        assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
922        assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
923        assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
924        assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
925        assert_eq!(
926            c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
927            vec![0, 1, 2, 3, 4]
928        );
929        assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
930        assert_eq!(
931            c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
932            vec![0, 1, 2, 3, 4]
933        );
934        assert_eq!(
935            c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
936            vec![0, 1, 2, 3, 4]
937        );
938        assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
939        assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
940        assert_eq!(
941            c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
942            vec![0, 1, 2, 3, 4]
943        );
944        assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
945        assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
946        assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
947        assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
948        assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
949        assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
950        assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
951        assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
952        assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
953        assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
954        assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
955        assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
956        assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
957        assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
958        assert_eq!(
959            c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
960            vec![0, 1, 2, 3, 4]
961        );
962        assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
963        assert_eq!(
964            c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
965            vec![0, 1, 2, 3, 4]
966        );
967        assert_eq!(
968            c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
969            vec![0, 1, 2, 3, 4]
970        );
971        assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
972        assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
973        assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
974        assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
975        assert_eq!(
976            c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
977            vec![0, 1, 2, 3, 4]
978        );
979        assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
980        assert_eq!(
981            c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
982            vec![0, 1, 2, 3, 4]
983        );
984        assert_eq!(
985            c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
986            vec![0, 3, 4, 5, 2]
987        );
988        assert_eq!(
989            c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
990            vec![0, 1, 2, 3, 4]
991        );
992        assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
993    }
994
995    #[test]
996    fn test_simplify() {
997        // 1-way merge
998        assert_eq!(c(&[0]).simplify(), c(&[0]));
999        // 3-way merge
1000        assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
1001        assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
1002        assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
1003        assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
1004        assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
1005        // 5-way merge
1006        assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
1007        assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
1008        assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
1009        assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
1010        assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
1011        assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
1012        assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
1013        assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
1014        assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
1015        assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
1016        assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
1017        assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
1018        assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
1019        assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
1020        assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
1021        assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
1022        assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
1023        assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
1024        assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
1025        assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
1026        assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1027        assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1028        assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1029        assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1030        assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1031        assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1032        assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1033        assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1034        assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1035        assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1036        assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1037        assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1038        assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1039        assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1040        assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1041        assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1042        assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1043        assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1044        assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1045        assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1046        assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1047        assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1048        assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1049        assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1050        assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1051        assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1052        assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1053        assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1054        assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1055        assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1056        assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1057        assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1058        assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1059    }
1060
1061    #[test]
1062    fn test_simplify_by() {
1063        fn enumerate_and_simplify_by(merge: Merge<i32>) -> Merge<(usize, i32)> {
1064            let enumerated = Merge::from_vec(merge.iter().copied().enumerate().collect_vec());
1065            enumerated.simplify_by(|&(_index, value)| value)
1066        }
1067
1068        // 1-way merge
1069        assert_eq!(enumerate_and_simplify_by(c(&[0])), c(&[(0, 0)]));
1070        // 3-way merge
1071        assert_eq!(enumerate_and_simplify_by(c(&[1, 0, 0])), c(&[(0, 1)]));
1072        assert_eq!(
1073            enumerate_and_simplify_by(c(&[1, 0, 2])),
1074            c(&[(0, 1), (1, 0), (2, 2)])
1075        );
1076        // 5-way merge
1077        assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 0])), c(&[(4, 0)]));
1078        assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 1])), c(&[(4, 1)]));
1079        assert_eq!(
1080            enumerate_and_simplify_by(c(&[0, 0, 0, 1, 2])),
1081            c(&[(2, 0), (3, 1), (4, 2)])
1082        );
1083        assert_eq!(
1084            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 0])),
1085            c(&[(0, 0), (1, 1), (4, 0)])
1086        );
1087        assert_eq!(
1088            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 2])),
1089            c(&[(0, 0), (1, 1), (4, 2)])
1090        );
1091        assert_eq!(
1092            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 3])),
1093            c(&[(0, 0), (1, 1), (4, 3)])
1094        );
1095        assert_eq!(
1096            enumerate_and_simplify_by(c(&[0, 1, 2, 3, 4])),
1097            c(&[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])
1098        );
1099    }
1100
1101    #[test]
1102    fn test_update_from_simplified() {
1103        // 1-way merge
1104        assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1105        // 3-way merge
1106        assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1107        assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1108        assert_eq!(
1109            c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1110            c(&[2, 1, 3])
1111        );
1112        // 5-way merge
1113        assert_eq!(
1114            c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1115            c(&[0, 0, 0, 0, 1])
1116        );
1117        assert_eq!(
1118            c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1119            c(&[0, 0, 2, 3, 1])
1120        );
1121        assert_eq!(
1122            c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1123            c(&[0, 3, 1, 0, 2])
1124        );
1125        assert_eq!(
1126            c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1127            c(&[3, 1, 4, 2, 5])
1128        );
1129
1130        assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1131        // Check that the `3`s are replaced correctly and that `4` ends up in the
1132        // correct position.
1133        assert_eq!(
1134            c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1135            c(&[0, 0, 10, 1, 11, 2, 4])
1136        );
1137    }
1138
1139    #[test]
1140    fn test_merge_invariants() {
1141        fn check_invariants(terms: &[u32]) {
1142            let merge = Merge::from_vec(terms.to_vec());
1143            // `simplify()` is idempotent
1144            assert_eq!(
1145                merge.simplify().simplify(),
1146                merge.simplify(),
1147                "simplify() not idempotent for {merge:?}"
1148            );
1149            // `resolve_trivial()` is unaffected by `simplify()`
1150            assert_eq!(
1151                merge.simplify().resolve_trivial(SameChange::Accept),
1152                merge.resolve_trivial(SameChange::Accept),
1153                "simplify() changed result of resolve_trivial() for {merge:?}"
1154            );
1155        }
1156        // 1-way merge
1157        check_invariants(&[0]);
1158        for i in 0..=1 {
1159            for j in 0..=i + 1 {
1160                // 3-way merge
1161                check_invariants(&[i, 0, j]);
1162                for k in 0..=j + 1 {
1163                    for l in 0..=k + 1 {
1164                        // 5-way merge
1165                        check_invariants(&[0, i, j, k, l]);
1166                    }
1167                }
1168            }
1169        }
1170    }
1171
1172    #[test]
1173    fn test_swap_remove() {
1174        let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1175        assert_eq!(x.swap_remove(0, 1), (1, 2));
1176        assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1177        assert_eq!(x.swap_remove(1, 0), (3, 0));
1178        assert_eq!(x, c(&[4, 5, 6]));
1179        assert_eq!(x.swap_remove(0, 1), (5, 6));
1180        assert_eq!(x, c(&[4]));
1181    }
1182
1183    #[test]
1184    fn test_pad_to() {
1185        let mut x = c(&[1]);
1186        x.pad_to(3, &2);
1187        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1188        // No change if the requested size is smaller
1189        x.pad_to(1, &3);
1190        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1191    }
1192
1193    #[test]
1194    fn test_iter() {
1195        // 1-way merge
1196        assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1197        // 5-way merge
1198        assert_eq!(
1199            c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1200            vec![&1, &2, &3, &4, &5]
1201        );
1202    }
1203
1204    #[test]
1205    fn test_from_iter() {
1206        // 1-way merge
1207        assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1208        // 5-way merge
1209        assert_eq!(
1210            MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1211            c(&[1, 2, 3, 4, 5])
1212        );
1213    }
1214
1215    #[test]
1216    #[should_panic]
1217    fn test_from_iter_empty() {
1218        MergeBuilder::from_iter([1; 0]).build();
1219    }
1220
1221    #[test]
1222    #[should_panic]
1223    fn test_from_iter_even() {
1224        MergeBuilder::from_iter([1, 2]).build();
1225    }
1226
1227    #[test]
1228    fn test_extend() {
1229        // 1-way merge
1230        let mut builder: MergeBuilder<i32> = Default::default();
1231        builder.extend([1]);
1232        assert_eq!(builder.build(), c(&[1]));
1233        // 5-way merge
1234        let mut builder: MergeBuilder<i32> = Default::default();
1235        builder.extend([1, 2]);
1236        builder.extend([3, 4, 5]);
1237        assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1238    }
1239
1240    #[test]
1241    fn test_map() {
1242        fn increment(i: &i32) -> i32 {
1243            i + 1
1244        }
1245        // 1-way merge
1246        assert_eq!(c(&[1]).map(increment), c(&[2]));
1247        // 3-way merge
1248        assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1249    }
1250
1251    #[test]
1252    fn test_try_map() {
1253        fn sqrt(i: &i32) -> Result<i32, ()> {
1254            if *i >= 0 {
1255                Ok(f64::from(*i).sqrt() as i32)
1256            } else {
1257                Err(())
1258            }
1259        }
1260        // 1-way merge
1261        assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1262        assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1263        // 3-way merge
1264        assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1265        assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1266        assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1267    }
1268
1269    #[test]
1270    fn test_flatten() {
1271        // 1-way merge of 1-way merge
1272        assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1273        // 1-way merge of 3-way merge
1274        assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1275        // 3-way merge of 1-way merges
1276        assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1277        // 3-way merge of 3-way merges
1278        assert_eq!(
1279            c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1280            c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1281        );
1282    }
1283
1284    #[test]
1285    fn test_zip() {
1286        // Zip of 1-way merges
1287        assert_eq!(c(&[1]).zip(c(&[2])), c(&[(1, 2)]));
1288        // Zip of 3-way merges
1289        assert_eq!(
1290            c(&[1, 2, 3]).zip(c(&[4, 5, 6])),
1291            c(&[(1, 4), (2, 5), (3, 6)])
1292        );
1293    }
1294
1295    #[test]
1296    fn test_unzip() {
1297        // 1-way merge
1298        assert_eq!(c(&[(1, 2)]).unzip(), (c(&[1]), c(&[2])));
1299        // 3-way merge
1300        assert_eq!(
1301            c(&[(1, 4), (2, 5), (3, 6)]).unzip(),
1302            (c(&[1, 2, 3]), c(&[4, 5, 6]))
1303        );
1304    }
1305}