Skip to main content

jj_lib/
merge.rs

1// Copyright 2023 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Generic algorithms for working with merged values, plus specializations for
16//! some common types of merged values.
17
18use std::borrow::Borrow;
19use std::collections::HashMap;
20use std::fmt::Debug;
21use std::fmt::Formatter;
22use std::fmt::Write as _;
23use std::hash::Hash;
24use std::iter;
25use std::iter::zip;
26use std::ops::Deref;
27use std::slice;
28use std::sync::Arc;
29
30use futures::future::try_join_all;
31use itertools::Itertools as _;
32use smallvec::SmallVec;
33use smallvec::smallvec;
34use smallvec::smallvec_inline;
35
36use crate::backend::BackendResult;
37use crate::backend::CopyId;
38use crate::backend::FileId;
39use crate::backend::TreeValue;
40use crate::conflict_labels::ConflictLabels;
41use crate::content_hash::ContentHash;
42use crate::content_hash::DigestUpdate;
43use crate::repo_path::RepoPath;
44use crate::repo_path::RepoPathComponent;
45use crate::store::Store;
46use crate::tree::Tree;
47
48/// A generic diff/transition from one value to another.
49///
50/// This is not a diff in the `patch(1)` sense. See `diff::ContentDiff` for
51/// that.
52#[derive(Copy, Clone, Debug, PartialEq, Eq)]
53pub struct Diff<T> {
54    /// The state before
55    pub before: T,
56    /// The state after
57    pub after: T,
58}
59
60impl<T> Diff<T> {
61    /// Create a new diff
62    pub fn new(before: T, after: T) -> Self {
63        Self { before, after }
64    }
65
66    /// Apply a function to both values
67    pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Diff<U> {
68        Diff {
69            before: f(self.before),
70            after: f(self.after),
71        }
72    }
73
74    /// Combine a `Diff<T>` and a `Diff<U>` into a `Diff<(T, U)>`.
75    pub fn zip<U>(self, other: Diff<U>) -> Diff<(T, U)> {
76        Diff {
77            before: (self.before, other.before),
78            after: (self.after, other.after),
79        }
80    }
81
82    /// Inverts a diff, swapping the before and after terms.
83    pub fn invert(self) -> Self {
84        Self {
85            before: self.after,
86            after: self.before,
87        }
88    }
89
90    /// Convert a `&Diff<T>` into a `Diff<&T>`.
91    pub fn as_ref(&self) -> Diff<&T> {
92        Diff {
93            before: &self.before,
94            after: &self.after,
95        }
96    }
97
98    /// Converts a `Diff<T>` or `&Diff<T>` to `Diff<&T::Target>`. (e.g.
99    /// `Diff<String>` to `Diff<&str>`)
100    pub fn as_deref(&self) -> Diff<&T::Target>
101    where
102        T: Deref,
103    {
104        self.as_ref().map(Deref::deref)
105    }
106
107    /// Convert a diff into an array `[before, after]`.
108    pub fn into_array(self) -> [T; 2] {
109        [self.before, self.after]
110    }
111}
112
113impl<T: Eq> Diff<T> {
114    /// Whether the diff represents a change, i.e. if `before` and `after` are
115    /// not equal
116    pub fn is_changed(&self) -> bool {
117        self.before != self.after
118    }
119}
120
121/// Whether to resolve conflict that makes the same change at all sides.
122#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize)]
123#[serde(rename_all = "kebab-case")]
124pub enum SameChange {
125    /// Leaves same-change conflict unresolved.
126    Keep,
127    /// Resolves same-change conflict as if one side were unchanged.
128    /// (i.e. `A+(A-B)=A`)
129    ///
130    /// This matches what Git and Mercurial do (in the 3-way case at least), but
131    /// not what Darcs does. It means that repeated 3-way merging of multiple
132    /// trees may give different results depending on the order of merging.
133    Accept,
134}
135
136/// Attempt to resolve trivial conflicts between the inputs. There must be
137/// an odd number of terms.
138pub fn trivial_merge<T>(values: &[T], same_change: SameChange) -> Option<&T>
139where
140    T: Eq + Hash,
141{
142    assert!(
143        values.len() % 2 == 1,
144        "trivial_merge() requires an odd number of terms"
145    );
146    // Optimize the common cases of 3-way merge and 1-way (non-)merge
147    if let [add] = values {
148        return Some(add);
149    } else if let [add0, remove, add1] = values {
150        return if add0 == add1 && same_change == SameChange::Accept {
151            Some(add0)
152        } else if add0 == remove {
153            Some(add1)
154        } else if add1 == remove {
155            Some(add0)
156        } else {
157            None
158        };
159    }
160
161    // Number of occurrences of each value, with positive indexes counted as +1 and
162    // negative as -1, thereby letting positive and negative terms with the same
163    // value (i.e. key in the map) cancel each other.
164    let mut counts: HashMap<&T, i32> = HashMap::new();
165    for (value, n) in zip(values, [1, -1].into_iter().cycle()) {
166        counts.entry(value).and_modify(|e| *e += n).or_insert(n);
167    }
168
169    // Collect non-zero value. Values with a count of 0 means that they have
170    // canceled out.
171    counts.retain(|_, count| *count != 0);
172    if counts.len() == 1 {
173        // If there is a single value with a count of 1 left, then that is the result.
174        let (value, count) = counts.into_iter().next().unwrap();
175        assert_eq!(count, 1);
176        Some(value)
177    } else if counts.len() == 2 && same_change == SameChange::Accept {
178        // All sides made the same change.
179        let [(value1, count1), (value2, count2)] = counts.into_iter().next_array().unwrap();
180        assert_eq!(count1 + count2, 1);
181        if count1 > 0 {
182            Some(value1)
183        } else {
184            Some(value2)
185        }
186    } else {
187        None
188    }
189}
190
191/// A generic representation of merged values.
192///
193/// There is exactly one more `adds()` than `removes()`. When interpreted as a
194/// series of diffs, the merge's (i+1)-st add is matched with the i-th
195/// remove. The zeroth add is considered a diff from the non-existent state.
196#[derive(PartialEq, Eq, Hash, Clone, serde::Serialize)]
197#[serde(transparent)]
198pub struct Merge<T> {
199    /// Alternates between positive and negative terms, starting with positive.
200    values: SmallVec<[T; 1]>,
201}
202
203impl<T: Debug> Debug for Merge<T> {
204    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
205        // Format like an enum with two variants to make it less verbose in the common
206        // case of a resolved state.
207        if let Some(value) = self.as_resolved() {
208            f.debug_tuple("Resolved").field(value).finish()
209        } else {
210            f.debug_tuple("Conflicted").field(&self.values).finish()
211        }
212    }
213}
214
215impl<T> Merge<T> {
216    /// Creates a `Merge` from the given values, in which positive and negative
217    /// terms alternate.
218    pub fn from_vec(values: impl Into<SmallVec<[T; 1]>>) -> Self {
219        let values = values.into();
220        assert!(values.len() % 2 != 0, "must have an odd number of terms");
221        Self { values }
222    }
223
224    /// Creates a new merge object from the given removes and adds.
225    pub fn from_removes_adds(
226        removes: impl IntoIterator<Item = T>,
227        adds: impl IntoIterator<Item = T>,
228    ) -> Self {
229        let removes = removes.into_iter();
230        let mut adds = adds.into_iter();
231        let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1);
232        values.push(adds.next().expect("must have at least one add"));
233        for diff in removes.zip_longest(adds) {
234            let (remove, add) = diff.both().expect("must have one more adds than removes");
235            values.extend([remove, add]);
236        }
237        Self { values }
238    }
239
240    /// Creates a `Merge` from a first side and a series of diffs to apply to
241    /// that side.
242    pub fn from_diffs(first_side: T, diffs: impl IntoIterator<Item = Diff<T>>) -> Self {
243        let values = iter::once(first_side)
244            .chain(diffs.into_iter().flat_map(Diff::into_array))
245            .collect();
246        Self { values }
247    }
248
249    /// Creates a `Merge` with a single resolved value.
250    pub const fn resolved(value: T) -> Self {
251        Self {
252            values: smallvec_inline![value],
253        }
254    }
255
256    /// Creates a `Merge` by repeating a single value.
257    pub fn repeated(value: T, num_sides: usize) -> Self
258    where
259        T: Clone,
260    {
261        Self {
262            values: smallvec![value; num_sides * 2 - 1],
263        }
264    }
265
266    /// Create a `Merge` from a `removes` and `adds`, padding with `None` to
267    /// make sure that there is exactly one more `adds` than `removes`.
268    pub fn from_legacy_form(
269        removes: impl IntoIterator<Item = T>,
270        adds: impl IntoIterator<Item = T>,
271    ) -> Merge<Option<T>> {
272        let removes = removes.into_iter();
273        let mut adds = adds.into_iter().fuse();
274        let mut values = smallvec_inline![adds.next()];
275        for diff in removes.zip_longest(adds) {
276            let (remove, add) = diff.map_any(Some, Some).or_default();
277            values.extend([remove, add]);
278        }
279        Merge { values }
280    }
281
282    /// The removed values, also called negative terms.
283    pub fn removes(&self) -> impl ExactSizeIterator<Item = &T> {
284        self.values[1..].iter().step_by(2)
285    }
286
287    /// The added values, also called positive terms.
288    pub fn adds(&self) -> impl ExactSizeIterator<Item = &T> {
289        self.values.iter().step_by(2)
290    }
291
292    /// Return the removed values and added values and take the ownership.
293    pub fn into_removes_adds(
294        self,
295    ) -> (
296        impl ExactSizeIterator<Item = T>,
297        impl ExactSizeIterator<Item = T>,
298    ) {
299        let (removes, adds): (Vec<_>, Vec<_>) = self
300            .values
301            .into_iter()
302            .enumerate()
303            .partition(|(n, _)| *n % 2 == 1);
304        (
305            removes.into_iter().map(|(_, item)| item),
306            adds.into_iter().map(|(_, item)| item),
307        )
308    }
309
310    /// Returns the zeroth added value, which is guaranteed to exist.
311    pub fn first(&self) -> &T {
312        &self.values[0]
313    }
314
315    /// Returns the `index`-th removed value, which is considered belonging to
316    /// the `index`-th diff pair.
317    pub fn get_remove(&self, index: usize) -> Option<&T> {
318        self.values.get(index * 2 + 1)
319    }
320
321    /// Returns the `index`-th added value, which is considered belonging to the
322    /// `index-1`-th diff pair. The zeroth add is a diff from the non-existent
323    /// state.
324    pub fn get_add(&self, index: usize) -> Option<&T> {
325        self.values.get(index * 2)
326    }
327
328    /// Removes the specified "removed"/"added" values. The removed slots are
329    /// replaced by the last "removed"/"added" values.
330    pub fn swap_remove(&mut self, remove_index: usize, add_index: usize) -> (T, T) {
331        // Swap with the last "added" and "removed" values in order.
332        let add = self.values.swap_remove(add_index * 2);
333        let remove = self.values.swap_remove(remove_index * 2 + 1);
334        (remove, add)
335    }
336
337    /// The number of positive terms in the conflict.
338    pub fn num_sides(&self) -> usize {
339        self.values.len() / 2 + 1
340    }
341
342    /// Whether this merge is resolved. Does not resolve trivial merges.
343    pub fn is_resolved(&self) -> bool {
344        self.values.len() == 1
345    }
346
347    /// Returns the resolved value, if this merge is resolved. Does not
348    /// resolve trivial merges.
349    pub fn as_resolved(&self) -> Option<&T> {
350        if let [value] = &self.values[..] {
351            Some(value)
352        } else {
353            None
354        }
355    }
356
357    /// Returns the resolved value, if this merge is resolved. Otherwise returns
358    /// the merge itself as an `Err`. Does not resolve trivial merges.
359    pub fn into_resolved(mut self) -> Result<T, Self> {
360        if self.values.len() == 1 {
361            Ok(self.values.pop().unwrap())
362        } else {
363            Err(self)
364        }
365    }
366
367    /// Returns a vector mapping of a value's index in the simplified merge to
368    /// its original index in the unsimplified merge.
369    ///
370    /// The merge is simplified by removing identical values in add and remove
371    /// values.
372    fn get_simplified_mapping(&self) -> Vec<usize>
373    where
374        T: PartialEq,
375    {
376        let unsimplified_len = self.values.len();
377        let mut simplified_to_original_indices = (0..unsimplified_len).collect_vec();
378
379        let mut add_index = 0;
380        while add_index < simplified_to_original_indices.len() {
381            let add = &self.values[simplified_to_original_indices[add_index]];
382            let mut remove_indices = simplified_to_original_indices
383                .iter()
384                .enumerate()
385                .skip(1)
386                .step_by(2);
387            if let Some((remove_index, _)) = remove_indices
388                .find(|&(_, original_remove_index)| &self.values[*original_remove_index] == add)
389            {
390                // Align the current "add" value to the `remove_index/2`-th diff, then
391                // delete the diff pair.
392                simplified_to_original_indices.swap(remove_index + 1, add_index);
393                simplified_to_original_indices.drain(remove_index..remove_index + 2);
394            } else {
395                add_index += 2;
396            }
397        }
398
399        simplified_to_original_indices
400    }
401
402    /// Apply the mapping returned by [`Self::get_simplified_mapping`].
403    #[must_use]
404    fn apply_simplified_mapping(&self, mapping: &[usize]) -> Self
405    where
406        T: Clone,
407    {
408        // Reorder values based on their new indices in the simplified merge.
409        let values = mapping
410            .iter()
411            .map(|index| self.values[*index].clone())
412            .collect();
413        Self { values }
414    }
415
416    /// Simplify the merge by joining diffs like A->B and B->C into A->C.
417    /// Also drops trivial diffs like A->A.
418    #[must_use]
419    pub fn simplify(&self) -> Self
420    where
421        T: PartialEq + Clone,
422    {
423        let mapping = self.get_simplified_mapping();
424        self.apply_simplified_mapping(&mapping)
425    }
426
427    /// Simplify the merge, using a function to choose which values to compare.
428    #[must_use]
429    pub fn simplify_by<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Self
430    where
431        T: Clone,
432        U: PartialEq,
433    {
434        let mapping = self.map(f).get_simplified_mapping();
435        self.apply_simplified_mapping(&mapping)
436    }
437
438    /// Updates the merge based on the given simplified merge.
439    pub fn update_from_simplified(mut self, simplified: Self) -> Self
440    where
441        T: PartialEq,
442    {
443        let mapping = self.get_simplified_mapping();
444        assert_eq!(mapping.len(), simplified.values.len());
445        for (index, value) in mapping.into_iter().zip(simplified.values) {
446            self.values[index] = value;
447        }
448        self
449    }
450
451    /// If this merge can be trivially resolved, returns the value it resolves
452    /// to.
453    pub fn resolve_trivial(&self, same_change: SameChange) -> Option<&T>
454    where
455        T: Eq + Hash,
456    {
457        trivial_merge(&self.values, same_change)
458    }
459
460    /// Pads this merge with to the specified number of sides with the specified
461    /// value. No-op if the requested size is not larger than the current size.
462    pub fn pad_to(&mut self, num_sides: usize, value: &T)
463    where
464        T: Clone,
465    {
466        if num_sides <= self.num_sides() {
467            return;
468        }
469        self.values.resize(num_sides * 2 - 1, value.clone());
470    }
471
472    /// Returns a slice containing the terms. The items will alternate between
473    /// positive and negative terms, starting with positive (since there's one
474    /// more of those).
475    pub fn as_slice(&self) -> &[T] {
476        &self.values
477    }
478
479    /// Returns an iterator over references to the terms. The items will
480    /// alternate between positive and negative terms, starting with
481    /// positive (since there's one more of those).
482    pub fn iter(&self) -> slice::Iter<'_, T> {
483        self.values.iter()
484    }
485
486    /// A version of `Merge::iter()` that iterates over mutable references.
487    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
488        self.values.iter_mut()
489    }
490
491    /// Creates a new merge by applying `f` to each remove and add.
492    pub fn map<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> Merge<U> {
493        let values = self.values.iter().map(f).collect();
494        Merge { values }
495    }
496
497    /// Creates a new merge by applying `f` to each remove and add, consuming
498    /// `self`.
499    pub fn into_map<U>(self, f: impl FnMut(T) -> U) -> Merge<U> {
500        let values = self.values.into_iter().map(f).collect();
501        Merge { values }
502    }
503
504    /// Creates a new merge by applying `f` to each remove and add, returning
505    /// `Err` if `f` returns `Err` for any of them.
506    pub fn try_map<'a, U, E>(
507        &'a self,
508        f: impl FnMut(&'a T) -> Result<U, E>,
509    ) -> Result<Merge<U>, E> {
510        let values = self.values.iter().map(f).try_collect()?;
511        Ok(Merge { values })
512    }
513
514    /// Creates a new merge by applying the async function `f` to each remove
515    /// and add, running them concurrently, and returning `Err` if `f`
516    /// returns `Err` for any of them.
517    pub async fn try_map_async<'a, F, U, E>(
518        &'a self,
519        f: impl FnMut(&'a T) -> F,
520    ) -> Result<Merge<U>, E>
521    where
522        F: Future<Output = Result<U, E>>,
523    {
524        let values = try_join_all(self.values.iter().map(f)).await?;
525        Ok(Merge {
526            values: values.into(),
527        })
528    }
529
530    /// Converts a `&Merge<T>` into a `Merge<&T>`.
531    pub fn as_ref(&self) -> Merge<&T> {
532        let values = self.values.iter().collect();
533        Merge { values }
534    }
535
536    /// Zip two merges which have the same number of terms. Panics if the merges
537    /// don't have the same number of terms.
538    pub fn zip<U>(self, other: Merge<U>) -> Merge<(T, U)> {
539        assert_eq!(self.values.len(), other.values.len());
540        let values = self.values.into_iter().zip(other.values).collect();
541        Merge { values }
542    }
543}
544
545impl<T, U> Merge<(T, U)> {
546    /// Unzips a merge of pairs into a pair of merges.
547    pub fn unzip(self) -> (Merge<T>, Merge<U>) {
548        let (left, right) = self.values.into_iter().unzip();
549        (Merge { values: left }, Merge { values: right })
550    }
551}
552
553impl<T> Merge<&'_ T> {
554    /// Convert a `Merge<&T>` into a `Merge<T>` by cloning each term.
555    pub fn cloned(&self) -> Merge<T>
556    where
557        T: Clone,
558    {
559        self.map(|&term| term.clone())
560    }
561}
562
563/// Helper for consuming items from an iterator and then creating a `Merge`.
564///
565/// By not collecting directly into `Merge`, we can avoid creating invalid
566/// instances of it. If we had `Merge::from_iter()` we would need to allow it to
567/// accept iterators of any length (including 0). We couldn't make it panic on
568/// even lengths because we can get passed such iterators from e.g.
569/// `Option::from_iter()`. By collecting into `MergeBuilder` instead, we move
570/// the checking until after `from_iter()` (to `MergeBuilder::build()`).
571#[derive(Clone, Debug, PartialEq, Eq)]
572pub struct MergeBuilder<T> {
573    values: SmallVec<[T; 1]>,
574}
575
576impl<T> Default for MergeBuilder<T> {
577    fn default() -> Self {
578        Self {
579            values: Default::default(),
580        }
581    }
582}
583
584impl<T> MergeBuilder<T> {
585    /// Requires that exactly one more "adds" than "removes" have been added to
586    /// this builder.
587    pub fn build(self) -> Merge<T> {
588        Merge::from_vec(self.values)
589    }
590}
591
592impl<T> IntoIterator for Merge<T> {
593    type Item = T;
594    type IntoIter = smallvec::IntoIter<[T; 1]>;
595
596    fn into_iter(self) -> Self::IntoIter {
597        self.values.into_iter()
598    }
599}
600
601impl<'a, T> IntoIterator for &'a Merge<T> {
602    type Item = &'a T;
603    type IntoIter = slice::Iter<'a, T>;
604
605    fn into_iter(self) -> Self::IntoIter {
606        self.iter()
607    }
608}
609
610impl<'a, T> IntoIterator for &'a mut Merge<T> {
611    type Item = &'a mut T;
612    type IntoIter = slice::IterMut<'a, T>;
613
614    fn into_iter(self) -> Self::IntoIter {
615        self.iter_mut()
616    }
617}
618
619impl<T> FromIterator<T> for MergeBuilder<T> {
620    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
621        let mut builder = Self::default();
622        builder.extend(iter);
623        builder
624    }
625}
626
627impl<T> Extend<T> for MergeBuilder<T> {
628    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
629        self.values.extend(iter);
630    }
631}
632
633impl<T> Merge<Option<T>> {
634    /// Creates a resolved merge with a value of `None`.
635    pub fn absent() -> Self {
636        Self::resolved(None)
637    }
638
639    /// Creates a resolved merge with a value of `Some(value)`.
640    pub fn normal(value: T) -> Self {
641        Self::resolved(Some(value))
642    }
643
644    /// Whether this represents a resolved value of `None`.
645    pub fn is_absent(&self) -> bool {
646        matches!(self.as_resolved(), Some(None))
647    }
648
649    /// The opposite of `is_absent()`.
650    pub fn is_present(&self) -> bool {
651        !self.is_absent()
652    }
653
654    /// Returns the value if this is present and non-conflicting.
655    pub fn as_normal(&self) -> Option<&T> {
656        self.as_resolved()?.as_ref()
657    }
658
659    /// Creates lists of `removes` and `adds` from a `Merge` by dropping
660    /// `None` values. Note that the conversion is lossy: the order of `None`
661    /// values is not preserved when converting back to a `Merge`.
662    pub fn into_legacy_form(self) -> (Vec<T>, Vec<T>) {
663        // Allocate the maximum size assuming there would be few `None`s.
664        let mut removes = Vec::with_capacity(self.values.len() / 2);
665        let mut adds = Vec::with_capacity(self.values.len() / 2 + 1);
666        let mut values = self.values.into_iter();
667        adds.extend(values.next().unwrap());
668        while let Some(remove) = values.next() {
669            removes.extend(remove);
670            adds.extend(values.next().unwrap());
671        }
672        (removes, adds)
673    }
674}
675
676impl<T: Clone> Merge<Option<&T>> {
677    /// Creates a new merge by cloning inner `Option<&T>`s.
678    pub fn cloned(&self) -> Merge<Option<T>> {
679        self.map(|value| value.cloned())
680    }
681}
682
683impl<T> Merge<Merge<T>> {
684    /// Flattens a nested merge into a regular merge.
685    ///
686    /// Let's say we have a 3-way merge of 3-way merges like this:
687    ///
688    /// ```text
689    /// 4 5   7 8
690    ///  3     6
691    ///    1 2
692    ///     0
693    /// ```
694    ///
695    /// Flattening that results in this 9-way merge:
696    ///
697    /// ```text
698    /// 4 5 0 7 8
699    ///  3 2 1 6
700    /// ```
701    pub fn flatten(self) -> Merge<T> {
702        let mut outer_values = self.values.into_iter();
703        let mut result = outer_values.next().unwrap();
704        while let Some(mut remove) = outer_values.next() {
705            // Add removes reversed, and with the first element moved last, so we preserve
706            // the diffs
707            remove.values.rotate_left(1);
708            for i in 0..remove.values.len() / 2 {
709                remove.values.swap(i * 2, i * 2 + 1);
710            }
711            result.values.extend(remove.values);
712            let add = outer_values.next().unwrap();
713            result.values.extend(add.values);
714        }
715        result
716    }
717}
718
719impl<T: ContentHash> ContentHash for Merge<T> {
720    fn hash(&self, state: &mut impl DigestUpdate) {
721        self.values.hash(state);
722    }
723}
724
725/// Borrowed `MergedTreeValue`.
726pub type MergedTreeVal<'a> = Merge<Option<&'a TreeValue>>;
727
728/// The value at a given path in a commit.
729///
730/// It depends on the context whether it can be absent
731/// (`Merge::is_absent()`). For example, when getting the value at a
732/// specific path, it may be, but when iterating over entries in a
733/// tree, it shouldn't be.
734pub type MergedTreeValue = Merge<Option<TreeValue>>;
735
736impl<T> Merge<Option<T>>
737where
738    T: Borrow<TreeValue>,
739{
740    /// Whether this merge should be recursed into when doing directory walks.
741    pub fn is_tree(&self) -> bool {
742        self.is_present()
743            && self.iter().all(|value| {
744                matches!(
745                    borrow_tree_value(value.as_ref()),
746                    Some(TreeValue::Tree(_)) | None
747                )
748            })
749    }
750
751    /// Whether this merge is present and not a tree
752    pub fn is_file_like(&self) -> bool {
753        self.is_present() && !self.is_tree()
754    }
755
756    /// If this merge contains only files or absent entries, returns a merge of
757    /// the `FileId`s. The executable bits and copy IDs will be ignored. Use
758    /// `Merge::with_new_file_ids()` to produce a new merge with the original
759    /// executable bits preserved.
760    pub fn to_file_merge(&self) -> Option<Merge<Option<FileId>>> {
761        let file_ids = self
762            .try_map(|term| match borrow_tree_value(term.as_ref()) {
763                None => Ok(None),
764                Some(TreeValue::File {
765                    id,
766                    executable: _,
767                    copy_id: _,
768                }) => Ok(Some(id.clone())),
769                _ => Err(()),
770            })
771            .ok()?;
772
773        Some(file_ids)
774    }
775
776    /// If this merge contains only files or absent entries, returns a merge of
777    /// the files' executable bits.
778    pub fn to_executable_merge(&self) -> Option<Merge<Option<bool>>> {
779        self.try_map(|term| match borrow_tree_value(term.as_ref()) {
780            None => Ok(None),
781            Some(TreeValue::File {
782                id: _,
783                executable,
784                copy_id: _,
785            }) => Ok(Some(*executable)),
786            _ => Err(()),
787        })
788        .ok()
789    }
790
791    /// If this merge contains only files or absent entries, returns a merge of
792    /// the files' copy IDs.
793    pub fn to_copy_id_merge(&self) -> Option<Merge<Option<CopyId>>> {
794        self.try_map(|term| match borrow_tree_value(term.as_ref()) {
795            None => Ok(None),
796            Some(TreeValue::File {
797                id: _,
798                executable: _,
799                copy_id,
800            }) => Ok(Some(copy_id.clone())),
801            _ => Err(()),
802        })
803        .ok()
804    }
805
806    /// If every non-`None` term of a `MergedTreeValue`
807    /// is a `TreeValue::Tree`, this converts it to
808    /// a `Merge<Tree>`, with empty trees instead of
809    /// any `None` terms. Otherwise, returns `None`.
810    pub async fn to_tree_merge(
811        &self,
812        store: &Arc<Store>,
813        dir: &RepoPath,
814    ) -> BackendResult<Option<Merge<Tree>>> {
815        let tree_id_merge = self.try_map(|term| match borrow_tree_value(term.as_ref()) {
816            None => Ok(None),
817            Some(TreeValue::Tree(id)) => Ok(Some(id)),
818            Some(_) => Err(()),
819        });
820        if let Ok(tree_id_merge) = tree_id_merge {
821            Ok(Some(
822                tree_id_merge
823                    .try_map_async(async |id| {
824                        if let Some(id) = id {
825                            store.get_tree(dir.to_owned(), id).await
826                        } else {
827                            Ok(Tree::empty(store.clone(), dir.to_owned()))
828                        }
829                    })
830                    .await?,
831            ))
832        } else {
833            Ok(None)
834        }
835    }
836
837    /// Creates a new merge with the file ids from the given merge. In other
838    /// words, the executable bits and copy IDs from `self` will be preserved.
839    ///
840    /// The given `file_ids` should have the same shape as `self`. Only the
841    /// `FileId` values may differ.
842    pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
843        assert_eq!(self.values.len(), file_ids.values.len());
844        let values = zip(self, file_ids.iter().cloned())
845            .map(
846                |(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
847                    (
848                        Some(TreeValue::File {
849                            id: _,
850                            executable,
851                            copy_id,
852                        }),
853                        Some(id),
854                    ) => Some(TreeValue::File {
855                        id,
856                        executable: *executable,
857                        copy_id: copy_id.clone(),
858                    }),
859                    (None, None) => None,
860                    // New files are populated to preserve the materialized conflict. The file won't
861                    // be checked out to the disk. So the metadata is not important, and we will
862                    // just use the default values.
863                    (None, Some(id)) => Some(TreeValue::File {
864                        id,
865                        executable: false,
866                        copy_id: CopyId::placeholder(),
867                    }),
868                    (old, new) => panic!("incompatible update: {old:?} to {new:?}"),
869                },
870            )
871            .collect();
872        Merge { values }
873    }
874
875    /// Give a summary description of the conflict's "removes" and "adds"
876    pub fn describe(&self, labels: &ConflictLabels) -> String {
877        let mut buf = String::new();
878        writeln!(buf, "Conflict:").unwrap();
879        for (term, label) in self
880            .removes()
881            .enumerate()
882            .filter_map(|(i, term)| term.as_ref().map(|term| (term, labels.get_remove(i))))
883        {
884            write!(buf, "  Removing {}", describe_conflict_term(term.borrow())).unwrap();
885            if let Some(label) = label {
886                write!(buf, " ({label})").unwrap();
887            }
888            buf.push('\n');
889        }
890        for (term, label) in self
891            .adds()
892            .enumerate()
893            .filter_map(|(i, term)| term.as_ref().map(|term| (term, labels.get_add(i))))
894        {
895            write!(buf, "  Adding {}", describe_conflict_term(term.borrow())).unwrap();
896            if let Some(label) = label {
897                write!(buf, " ({label})").unwrap();
898            }
899            buf.push('\n');
900        }
901        buf
902    }
903}
904
905fn borrow_tree_value<T: Borrow<TreeValue> + ?Sized>(term: Option<&T>) -> Option<&TreeValue> {
906    term.map(|value| value.borrow())
907}
908
909fn describe_conflict_term(value: &TreeValue) -> String {
910    match value {
911        TreeValue::File {
912            id,
913            executable: false,
914            copy_id: _,
915        } => {
916            // TODO: include the copy here once we start using it
917            format!("file with id {id}")
918        }
919        TreeValue::File {
920            id,
921            executable: true,
922            copy_id: _,
923        } => {
924            // TODO: include the copy here once we start using it
925            format!("executable file with id {id}")
926        }
927        TreeValue::Symlink(id) => {
928            format!("symlink with id {id}")
929        }
930        TreeValue::Tree(id) => {
931            format!("tree with id {id}")
932        }
933        TreeValue::GitSubmodule(id) => {
934            format!("Git submodule with id {id}")
935        }
936    }
937}
938
939impl Merge<Tree> {
940    /// The directory that is shared by all trees in the merge.
941    pub fn dir(&self) -> &RepoPath {
942        debug_assert!(self.iter().map(|tree| tree.dir()).all_equal());
943        self.first().dir()
944    }
945
946    /// The value at the given basename. The value can be `Resolved` even if
947    /// `self` is conflicted, which happens if the value at the path can be
948    /// trivially merged. Does not recurse, so if `basename` refers to a Tree,
949    /// then a `TreeValue::Tree` will be returned.
950    pub fn value(&self, basename: &RepoPathComponent) -> MergedTreeVal<'_> {
951        if let Some(tree) = self.as_resolved() {
952            return Merge::resolved(tree.value(basename));
953        }
954        let same_change = self.first().store().merge_options().same_change;
955        let value = self.map(|tree| tree.value(basename));
956        if let Some(resolved) = value.resolve_trivial(same_change) {
957            return Merge::resolved(*resolved);
958        }
959        value
960    }
961
962    /// Gets the `Merge<Tree>` in a subdirectory of the current tree. If the
963    /// path doesn't correspond to a tree in any of the inputs to the merge,
964    /// then that entry will be replaced by an empty tree in the result.
965    pub async fn sub_tree(&self, name: &RepoPathComponent) -> BackendResult<Option<Self>> {
966        let store = self.first().store();
967        match self.value(name).into_resolved() {
968            Ok(Some(TreeValue::Tree(sub_tree_id))) => {
969                let subdir = self.dir().join(name);
970                Ok(Some(Self::resolved(
971                    store.get_tree(subdir, sub_tree_id).await?,
972                )))
973            }
974            Ok(_) => Ok(None),
975            Err(merge) => {
976                if !merge.is_tree() {
977                    return Ok(None);
978                }
979                let trees = merge
980                    .try_map_async(async |value| match value {
981                        Some(TreeValue::Tree(sub_tree_id)) => {
982                            let subdir = self.dir().join(name);
983                            store.get_tree(subdir, sub_tree_id).await
984                        }
985                        Some(_) => unreachable!(),
986                        None => {
987                            let subdir = self.dir().join(name);
988                            Ok(Tree::empty(store.clone(), subdir))
989                        }
990                    })
991                    .await?;
992                Ok(Some(trees))
993            }
994        }
995    }
996
997    /// Look up the tree at the given path.
998    pub async fn sub_tree_recursive(&self, path: &RepoPath) -> BackendResult<Option<Self>> {
999        let mut current_tree = self.clone();
1000        for name in path.components() {
1001            match current_tree.sub_tree(name).await? {
1002                None => {
1003                    return Ok(None);
1004                }
1005                Some(sub_tree) => {
1006                    current_tree = sub_tree;
1007                }
1008            }
1009        }
1010        Ok(Some(current_tree))
1011    }
1012}
1013
1014#[cfg(test)]
1015mod tests {
1016    use test_case::test_case;
1017
1018    use super::*;
1019
1020    #[test]
1021    fn test_diff_map() {
1022        let diff = Diff::new(1, 2);
1023        assert_eq!(diff.map(|x| x + 2), Diff::new(3, 4));
1024    }
1025
1026    #[test]
1027    fn test_diff_zip() {
1028        let diff1 = Diff::new(1, 2);
1029        let diff2 = Diff::new(3, 4);
1030        assert_eq!(diff1.zip(diff2), Diff::new((1, 3), (2, 4)));
1031    }
1032
1033    #[test]
1034    fn test_diff_invert() {
1035        let diff = Diff::new(1, 2);
1036        assert_eq!(diff.invert(), Diff::new(2, 1));
1037    }
1038
1039    #[test]
1040    fn test_diff_as_ref() {
1041        let diff = Diff::new(1, 2);
1042        assert_eq!(diff.as_ref(), Diff::new(&1, &2));
1043    }
1044
1045    #[test]
1046    fn test_diff_into_array() {
1047        let diff = Diff::new(1, 2);
1048        assert_eq!(diff.into_array(), [1, 2]);
1049    }
1050
1051    #[test]
1052    fn test_merge_from_diffs() {
1053        assert_eq!(Merge::from_diffs(1, []), Merge::resolved(1));
1054        assert_eq!(
1055            Merge::from_diffs(1, [Diff::new(2, 3)]),
1056            Merge::from_vec(vec![1, 2, 3])
1057        );
1058        assert_eq!(
1059            Merge::from_diffs(1, [Diff::new(2, 3), Diff::new(4, 5)]),
1060            Merge::from_vec(vec![1, 2, 3, 4, 5])
1061        );
1062    }
1063
1064    fn c<T: Clone>(terms: &[T]) -> Merge<T> {
1065        Merge::from_vec(terms.to_vec())
1066    }
1067
1068    #[test_case(SameChange::Keep)]
1069    #[test_case(SameChange::Accept)]
1070    fn test_trivial_merge(same_change: SameChange) {
1071        let accept_same_change = same_change == SameChange::Accept;
1072        let merge = |values| trivial_merge(values, same_change);
1073        assert_eq!(merge(&[0]), Some(&0));
1074        assert_eq!(merge(&[0, 0, 0]), Some(&0));
1075        assert_eq!(merge(&[0, 0, 1]), Some(&1));
1076        assert_eq!(merge(&[0, 1, 0]), accept_same_change.then_some(&0));
1077        assert_eq!(merge(&[0, 1, 1]), Some(&0));
1078        assert_eq!(merge(&[0, 1, 2]), None);
1079        assert_eq!(merge(&[0, 0, 0, 0, 0]), Some(&0));
1080        assert_eq!(merge(&[0, 0, 0, 0, 1]), Some(&1));
1081        assert_eq!(merge(&[0, 0, 0, 1, 0]), accept_same_change.then_some(&0));
1082        assert_eq!(merge(&[0, 0, 0, 1, 1]), Some(&0));
1083        assert_eq!(merge(&[0, 0, 0, 1, 2]), None);
1084        assert_eq!(merge(&[0, 0, 1, 0, 0]), Some(&1));
1085        assert_eq!(merge(&[0, 0, 1, 0, 1]), accept_same_change.then_some(&1));
1086        assert_eq!(merge(&[0, 0, 1, 0, 2]), None);
1087        assert_eq!(merge(&[0, 0, 1, 1, 0]), Some(&0));
1088        assert_eq!(merge(&[0, 0, 1, 1, 1]), Some(&1));
1089        assert_eq!(merge(&[0, 0, 1, 1, 2]), Some(&2));
1090        assert_eq!(merge(&[0, 0, 1, 2, 0]), None);
1091        assert_eq!(merge(&[0, 0, 1, 2, 1]), accept_same_change.then_some(&1));
1092        assert_eq!(merge(&[0, 0, 1, 2, 2]), Some(&1));
1093        assert_eq!(merge(&[0, 0, 1, 2, 3]), None);
1094        assert_eq!(merge(&[0, 1, 0, 0, 0]), accept_same_change.then_some(&0));
1095        assert_eq!(merge(&[0, 1, 0, 0, 1]), Some(&0));
1096        assert_eq!(merge(&[0, 1, 0, 0, 2]), None);
1097        assert_eq!(merge(&[0, 1, 0, 1, 0]), accept_same_change.then_some(&0));
1098        assert_eq!(merge(&[0, 1, 0, 1, 1]), accept_same_change.then_some(&0));
1099        assert_eq!(merge(&[0, 1, 0, 1, 2]), None);
1100        assert_eq!(merge(&[0, 1, 0, 2, 0]), None);
1101        assert_eq!(merge(&[0, 1, 0, 2, 1]), accept_same_change.then_some(&0));
1102        assert_eq!(merge(&[0, 1, 0, 2, 2]), accept_same_change.then_some(&0));
1103        assert_eq!(merge(&[0, 1, 0, 2, 3]), None);
1104        assert_eq!(merge(&[0, 1, 1, 0, 0]), Some(&0));
1105        assert_eq!(merge(&[0, 1, 1, 0, 1]), Some(&1));
1106        assert_eq!(merge(&[0, 1, 1, 0, 2]), Some(&2));
1107        assert_eq!(merge(&[0, 1, 1, 1, 0]), accept_same_change.then_some(&0));
1108        assert_eq!(merge(&[0, 1, 1, 1, 1]), Some(&0));
1109        assert_eq!(merge(&[0, 1, 1, 1, 2]), None);
1110        assert_eq!(merge(&[0, 1, 1, 2, 0]), accept_same_change.then_some(&0));
1111        assert_eq!(merge(&[0, 1, 1, 2, 1]), None);
1112        assert_eq!(merge(&[0, 1, 1, 2, 2]), Some(&0));
1113        assert_eq!(merge(&[0, 1, 1, 2, 3]), None);
1114        assert_eq!(merge(&[0, 1, 2, 0, 0]), None);
1115        assert_eq!(merge(&[0, 1, 2, 0, 1]), Some(&2));
1116        assert_eq!(merge(&[0, 1, 2, 0, 2]), accept_same_change.then_some(&2));
1117        assert_eq!(merge(&[0, 1, 2, 0, 3]), None);
1118        assert_eq!(merge(&[0, 1, 2, 1, 0]), None);
1119        assert_eq!(merge(&[0, 1, 2, 1, 1]), None);
1120        assert_eq!(merge(&[0, 1, 2, 1, 2]), None);
1121        assert_eq!(merge(&[0, 1, 2, 1, 3]), None);
1122        assert_eq!(merge(&[0, 1, 2, 2, 0]), accept_same_change.then_some(&0));
1123        assert_eq!(merge(&[0, 1, 2, 2, 1]), Some(&0));
1124        assert_eq!(merge(&[0, 1, 2, 2, 2]), None);
1125        assert_eq!(merge(&[0, 1, 2, 2, 3]), None);
1126        assert_eq!(merge(&[0, 1, 2, 3, 0]), None);
1127        assert_eq!(merge(&[0, 1, 2, 3, 1]), None);
1128        assert_eq!(merge(&[0, 1, 2, 3, 2]), None);
1129        assert_eq!(merge(&[0, 1, 2, 3, 3]), None);
1130        assert_eq!(merge(&[0, 1, 2, 3, 4]), None);
1131    }
1132
1133    #[test]
1134    fn test_legacy_form_conversion() {
1135        fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
1136        where
1137            T: Clone + PartialEq + std::fmt::Debug,
1138        {
1139            assert_eq!(merge.clone().into_legacy_form(), legacy_form);
1140            assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
1141        }
1142        // Non-conflict
1143        test_equivalent(
1144            (vec![], vec![0]),
1145            Merge::from_removes_adds(vec![], vec![Some(0)]),
1146        );
1147        // Regular 3-way conflict
1148        test_equivalent(
1149            (vec![0], vec![1, 2]),
1150            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), Some(2)]),
1151        );
1152        // Modify/delete conflict
1153        test_equivalent(
1154            (vec![0], vec![1]),
1155            Merge::from_removes_adds(vec![Some(0)], vec![Some(1), None]),
1156        );
1157        // Add/add conflict
1158        test_equivalent(
1159            (vec![], vec![0, 1]),
1160            Merge::from_removes_adds(vec![None], vec![Some(0), Some(1)]),
1161        );
1162        // 5-way conflict
1163        test_equivalent(
1164            (vec![0, 1], vec![2, 3, 4]),
1165            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
1166        );
1167        // 5-way delete/delete conflict
1168        test_equivalent(
1169            (vec![0, 1], vec![]),
1170            Merge::from_removes_adds(vec![Some(0), Some(1)], vec![None, None, None]),
1171        );
1172    }
1173
1174    #[test]
1175    fn test_as_resolved() {
1176        assert_eq!(
1177            Merge::from_removes_adds(vec![], vec![0]).as_resolved(),
1178            Some(&0)
1179        );
1180        // Even a trivially resolvable merge is not resolved
1181        assert_eq!(
1182            Merge::from_removes_adds(vec![0], vec![0, 1]).as_resolved(),
1183            None
1184        );
1185    }
1186
1187    #[test]
1188    fn test_get_simplified_mapping() {
1189        // 1-way merge
1190        assert_eq!(c(&[0]).get_simplified_mapping(), vec![0]);
1191        // 3-way merge
1192        assert_eq!(c(&[0, 0, 0]).get_simplified_mapping(), vec![2]);
1193        assert_eq!(c(&[0, 0, 1]).get_simplified_mapping(), vec![2]);
1194        assert_eq!(c(&[0, 1, 0]).get_simplified_mapping(), vec![0, 1, 2]);
1195        assert_eq!(c(&[0, 1, 1]).get_simplified_mapping(), vec![0]);
1196        assert_eq!(c(&[0, 1, 2]).get_simplified_mapping(), vec![0, 1, 2]);
1197        // 5-way merge
1198        assert_eq!(c(&[0, 0, 0, 0, 0]).get_simplified_mapping(), vec![4]);
1199        assert_eq!(c(&[0, 0, 0, 0, 1]).get_simplified_mapping(), vec![4]);
1200        assert_eq!(c(&[0, 0, 0, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
1201        assert_eq!(c(&[0, 0, 0, 1, 1]).get_simplified_mapping(), vec![2]);
1202        assert_eq!(c(&[0, 0, 0, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1203        assert_eq!(c(&[0, 0, 1, 0, 0]).get_simplified_mapping(), vec![2]);
1204        assert_eq!(c(&[0, 0, 1, 0, 1]).get_simplified_mapping(), vec![2, 3, 4]);
1205        assert_eq!(c(&[0, 0, 1, 0, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1206        assert_eq!(c(&[0, 0, 1, 1, 0]).get_simplified_mapping(), vec![4]);
1207        assert_eq!(c(&[0, 0, 1, 1, 1]).get_simplified_mapping(), vec![4]);
1208        assert_eq!(c(&[0, 0, 1, 1, 2]).get_simplified_mapping(), vec![4]);
1209        assert_eq!(c(&[0, 0, 2, 1, 0]).get_simplified_mapping(), vec![2, 3, 4]);
1210        assert_eq!(c(&[0, 0, 2, 1, 1]).get_simplified_mapping(), vec![2]);
1211        assert_eq!(c(&[0, 0, 2, 1, 2]).get_simplified_mapping(), vec![2, 3, 4]);
1212        assert_eq!(c(&[0, 0, 2, 1, 3]).get_simplified_mapping(), vec![2, 3, 4]);
1213        assert_eq!(c(&[0, 1, 0, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1214        assert_eq!(c(&[0, 1, 0, 0, 1]).get_simplified_mapping(), vec![2]);
1215        assert_eq!(c(&[0, 1, 0, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1216        assert_eq!(
1217            c(&[0, 1, 0, 1, 0]).get_simplified_mapping(),
1218            vec![0, 1, 2, 3, 4]
1219        );
1220        assert_eq!(c(&[0, 1, 0, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1221        assert_eq!(
1222            c(&[0, 1, 0, 1, 2]).get_simplified_mapping(),
1223            vec![0, 1, 2, 3, 4]
1224        );
1225        assert_eq!(
1226            c(&[0, 1, 0, 2, 0]).get_simplified_mapping(),
1227            vec![0, 1, 2, 3, 4]
1228        );
1229        assert_eq!(c(&[0, 1, 0, 2, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1230        assert_eq!(c(&[0, 1, 0, 2, 2]).get_simplified_mapping(), vec![0, 1, 2]);
1231        assert_eq!(
1232            c(&[0, 1, 0, 2, 3]).get_simplified_mapping(),
1233            vec![0, 1, 2, 3, 4]
1234        );
1235        assert_eq!(c(&[0, 1, 1, 0, 0]).get_simplified_mapping(), vec![4]);
1236        assert_eq!(c(&[0, 1, 1, 0, 1]).get_simplified_mapping(), vec![2]);
1237        assert_eq!(c(&[0, 1, 1, 0, 2]).get_simplified_mapping(), vec![4]);
1238        assert_eq!(c(&[0, 1, 1, 1, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1239        assert_eq!(c(&[0, 1, 1, 1, 1]).get_simplified_mapping(), vec![0]);
1240        assert_eq!(c(&[0, 1, 1, 1, 2]).get_simplified_mapping(), vec![0, 3, 4]);
1241        assert_eq!(c(&[0, 1, 1, 2, 0]).get_simplified_mapping(), vec![0, 3, 4]);
1242        assert_eq!(c(&[0, 1, 1, 2, 1]).get_simplified_mapping(), vec![0, 3, 4]);
1243        assert_eq!(c(&[0, 1, 1, 2, 2]).get_simplified_mapping(), vec![0]);
1244        assert_eq!(c(&[0, 1, 1, 2, 3]).get_simplified_mapping(), vec![0, 3, 4]);
1245        assert_eq!(c(&[0, 1, 2, 0, 0]).get_simplified_mapping(), vec![4, 1, 2]);
1246        assert_eq!(c(&[0, 1, 2, 0, 1]).get_simplified_mapping(), vec![2]);
1247        assert_eq!(c(&[0, 1, 2, 0, 2]).get_simplified_mapping(), vec![4, 1, 2]);
1248        assert_eq!(c(&[0, 1, 2, 0, 3]).get_simplified_mapping(), vec![4, 1, 2]);
1249        assert_eq!(
1250            c(&[0, 1, 2, 1, 0]).get_simplified_mapping(),
1251            vec![0, 1, 2, 3, 4]
1252        );
1253        assert_eq!(c(&[0, 1, 2, 1, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1254        assert_eq!(
1255            c(&[0, 1, 2, 1, 2]).get_simplified_mapping(),
1256            vec![0, 1, 2, 3, 4]
1257        );
1258        assert_eq!(
1259            c(&[0, 1, 2, 1, 3]).get_simplified_mapping(),
1260            vec![0, 1, 2, 3, 4]
1261        );
1262        assert_eq!(c(&[0, 1, 2, 2, 0]).get_simplified_mapping(), vec![0, 1, 4]);
1263        assert_eq!(c(&[0, 1, 2, 2, 1]).get_simplified_mapping(), vec![0]);
1264        assert_eq!(c(&[0, 1, 2, 2, 2]).get_simplified_mapping(), vec![0, 1, 4]);
1265        assert_eq!(c(&[0, 1, 2, 2, 3]).get_simplified_mapping(), vec![0, 1, 4]);
1266        assert_eq!(
1267            c(&[0, 1, 2, 3, 0]).get_simplified_mapping(),
1268            vec![0, 1, 2, 3, 4]
1269        );
1270        assert_eq!(c(&[0, 1, 2, 3, 1]).get_simplified_mapping(), vec![0, 3, 2]);
1271        assert_eq!(
1272            c(&[0, 1, 2, 3, 2]).get_simplified_mapping(),
1273            vec![0, 1, 2, 3, 4]
1274        );
1275        assert_eq!(
1276            c(&[0, 1, 2, 3, 4, 5, 1]).get_simplified_mapping(),
1277            vec![0, 3, 4, 5, 2]
1278        );
1279        assert_eq!(
1280            c(&[0, 1, 2, 3, 4]).get_simplified_mapping(),
1281            vec![0, 1, 2, 3, 4]
1282        );
1283        assert_eq!(c(&[2, 0, 3, 1, 1]).get_simplified_mapping(), vec![0, 1, 2]);
1284    }
1285
1286    #[test]
1287    fn test_simplify() {
1288        // 1-way merge
1289        assert_eq!(c(&[0]).simplify(), c(&[0]));
1290        // 3-way merge
1291        assert_eq!(c(&[0, 0, 0]).simplify(), c(&[0]));
1292        assert_eq!(c(&[0, 0, 1]).simplify(), c(&[1]));
1293        assert_eq!(c(&[1, 0, 0]).simplify(), c(&[1]));
1294        assert_eq!(c(&[1, 0, 1]).simplify(), c(&[1, 0, 1]));
1295        assert_eq!(c(&[1, 0, 2]).simplify(), c(&[1, 0, 2]));
1296        // 5-way merge
1297        assert_eq!(c(&[0, 0, 0, 0, 0]).simplify(), c(&[0]));
1298        assert_eq!(c(&[0, 0, 0, 0, 1]).simplify(), c(&[1]));
1299        assert_eq!(c(&[0, 0, 0, 1, 0]).simplify(), c(&[0, 1, 0]));
1300        assert_eq!(c(&[0, 0, 0, 1, 1]).simplify(), c(&[0]));
1301        assert_eq!(c(&[0, 0, 0, 1, 2]).simplify(), c(&[0, 1, 2]));
1302        assert_eq!(c(&[0, 0, 1, 0, 0]).simplify(), c(&[1]));
1303        assert_eq!(c(&[0, 0, 1, 0, 1]).simplify(), c(&[1, 0, 1]));
1304        assert_eq!(c(&[0, 0, 1, 0, 2]).simplify(), c(&[1, 0, 2]));
1305        assert_eq!(c(&[0, 0, 1, 1, 0]).simplify(), c(&[0]));
1306        assert_eq!(c(&[0, 0, 1, 1, 1]).simplify(), c(&[1]));
1307        assert_eq!(c(&[0, 0, 1, 1, 2]).simplify(), c(&[2]));
1308        assert_eq!(c(&[0, 0, 2, 1, 0]).simplify(), c(&[2, 1, 0]));
1309        assert_eq!(c(&[0, 0, 2, 1, 1]).simplify(), c(&[2]));
1310        assert_eq!(c(&[0, 0, 2, 1, 2]).simplify(), c(&[2, 1, 2]));
1311        assert_eq!(c(&[0, 0, 2, 1, 3]).simplify(), c(&[2, 1, 3]));
1312        assert_eq!(c(&[0, 1, 0, 0, 0]).simplify(), c(&[0, 1, 0]));
1313        assert_eq!(c(&[0, 1, 0, 0, 1]).simplify(), c(&[0]));
1314        assert_eq!(c(&[0, 1, 0, 0, 2]).simplify(), c(&[2, 1, 0]));
1315        assert_eq!(c(&[0, 1, 0, 1, 0]).simplify(), c(&[0, 1, 0, 1, 0]));
1316        assert_eq!(c(&[0, 1, 0, 1, 1]).simplify(), c(&[0, 1, 0]));
1317        assert_eq!(c(&[0, 1, 0, 1, 2]).simplify(), c(&[0, 1, 0, 1, 2]));
1318        assert_eq!(c(&[0, 1, 0, 2, 0]).simplify(), c(&[0, 1, 0, 2, 0]));
1319        assert_eq!(c(&[0, 1, 0, 2, 1]).simplify(), c(&[0, 2, 0]));
1320        assert_eq!(c(&[0, 1, 0, 2, 2]).simplify(), c(&[0, 1, 0]));
1321        assert_eq!(c(&[0, 1, 0, 2, 3]).simplify(), c(&[0, 1, 0, 2, 3]));
1322        assert_eq!(c(&[0, 1, 1, 0, 0]).simplify(), c(&[0]));
1323        assert_eq!(c(&[0, 1, 1, 0, 1]).simplify(), c(&[1]));
1324        assert_eq!(c(&[0, 1, 1, 0, 2]).simplify(), c(&[2]));
1325        assert_eq!(c(&[0, 1, 1, 1, 0]).simplify(), c(&[0, 1, 0]));
1326        assert_eq!(c(&[0, 1, 1, 1, 1]).simplify(), c(&[0]));
1327        assert_eq!(c(&[0, 1, 1, 1, 2]).simplify(), c(&[0, 1, 2]));
1328        assert_eq!(c(&[0, 1, 1, 2, 0]).simplify(), c(&[0, 2, 0]));
1329        assert_eq!(c(&[0, 1, 1, 2, 1]).simplify(), c(&[0, 2, 1]));
1330        assert_eq!(c(&[0, 1, 1, 2, 2]).simplify(), c(&[0]));
1331        assert_eq!(c(&[0, 1, 1, 2, 3]).simplify(), c(&[0, 2, 3]));
1332        assert_eq!(c(&[0, 1, 2, 0, 0]).simplify(), c(&[0, 1, 2]));
1333        assert_eq!(c(&[0, 1, 2, 0, 1]).simplify(), c(&[2]));
1334        assert_eq!(c(&[0, 1, 2, 0, 2]).simplify(), c(&[2, 1, 2]));
1335        assert_eq!(c(&[0, 1, 2, 0, 3]).simplify(), c(&[3, 1, 2]));
1336        assert_eq!(c(&[0, 1, 2, 1, 0]).simplify(), c(&[0, 1, 2, 1, 0]));
1337        assert_eq!(c(&[0, 1, 2, 1, 1]).simplify(), c(&[0, 1, 2]));
1338        assert_eq!(c(&[0, 1, 2, 1, 2]).simplify(), c(&[0, 1, 2, 1, 2]));
1339        assert_eq!(c(&[0, 1, 2, 1, 3]).simplify(), c(&[0, 1, 2, 1, 3]));
1340        assert_eq!(c(&[0, 1, 2, 2, 0]).simplify(), c(&[0, 1, 0]));
1341        assert_eq!(c(&[0, 1, 2, 2, 1]).simplify(), c(&[0]));
1342        assert_eq!(c(&[0, 1, 2, 2, 2]).simplify(), c(&[0, 1, 2]));
1343        assert_eq!(c(&[0, 1, 2, 2, 3]).simplify(), c(&[0, 1, 3]));
1344        assert_eq!(c(&[0, 1, 2, 3, 0]).simplify(), c(&[0, 1, 2, 3, 0]));
1345        assert_eq!(c(&[0, 1, 2, 3, 1]).simplify(), c(&[0, 3, 2]));
1346        assert_eq!(c(&[0, 1, 2, 3, 2]).simplify(), c(&[0, 1, 2, 3, 2]));
1347        assert_eq!(c(&[0, 1, 2, 3, 3]).simplify(), c(&[0, 1, 2]));
1348        assert_eq!(c(&[0, 1, 2, 3, 4]).simplify(), c(&[0, 1, 2, 3, 4]));
1349        assert_eq!(c(&[0, 1, 2, 3, 4, 5, 1]).simplify(), c(&[0, 3, 4, 5, 2]));
1350    }
1351
1352    #[test]
1353    fn test_simplify_by() {
1354        fn enumerate_and_simplify_by(merge: Merge<i32>) -> Merge<(usize, i32)> {
1355            let enumerated = Merge::from_vec(merge.iter().copied().enumerate().collect_vec());
1356            enumerated.simplify_by(|&(_index, value)| value)
1357        }
1358
1359        // 1-way merge
1360        assert_eq!(enumerate_and_simplify_by(c(&[0])), c(&[(0, 0)]));
1361        // 3-way merge
1362        assert_eq!(enumerate_and_simplify_by(c(&[1, 0, 0])), c(&[(0, 1)]));
1363        assert_eq!(
1364            enumerate_and_simplify_by(c(&[1, 0, 2])),
1365            c(&[(0, 1), (1, 0), (2, 2)])
1366        );
1367        // 5-way merge
1368        assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 0])), c(&[(4, 0)]));
1369        assert_eq!(enumerate_and_simplify_by(c(&[0, 0, 0, 0, 1])), c(&[(4, 1)]));
1370        assert_eq!(
1371            enumerate_and_simplify_by(c(&[0, 0, 0, 1, 2])),
1372            c(&[(2, 0), (3, 1), (4, 2)])
1373        );
1374        assert_eq!(
1375            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 0])),
1376            c(&[(0, 0), (1, 1), (4, 0)])
1377        );
1378        assert_eq!(
1379            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 2])),
1380            c(&[(0, 0), (1, 1), (4, 2)])
1381        );
1382        assert_eq!(
1383            enumerate_and_simplify_by(c(&[0, 1, 2, 2, 3])),
1384            c(&[(0, 0), (1, 1), (4, 3)])
1385        );
1386        assert_eq!(
1387            enumerate_and_simplify_by(c(&[0, 1, 2, 3, 4])),
1388            c(&[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])
1389        );
1390    }
1391
1392    #[test]
1393    fn test_update_from_simplified() {
1394        // 1-way merge
1395        assert_eq!(c(&[0]).update_from_simplified(c(&[1])), c(&[1]));
1396        // 3-way merge
1397        assert_eq!(c(&[0, 0, 0]).update_from_simplified(c(&[1])), c(&[0, 0, 1]));
1398        assert_eq!(c(&[1, 0, 0]).update_from_simplified(c(&[2])), c(&[2, 0, 0]));
1399        assert_eq!(
1400            c(&[1, 0, 2]).update_from_simplified(c(&[2, 1, 3])),
1401            c(&[2, 1, 3])
1402        );
1403        // 5-way merge
1404        assert_eq!(
1405            c(&[0, 0, 0, 0, 0]).update_from_simplified(c(&[1])),
1406            c(&[0, 0, 0, 0, 1])
1407        );
1408        assert_eq!(
1409            c(&[0, 0, 0, 1, 0]).update_from_simplified(c(&[2, 3, 1])),
1410            c(&[0, 0, 2, 3, 1])
1411        );
1412        assert_eq!(
1413            c(&[0, 1, 0, 0, 0]).update_from_simplified(c(&[2, 3, 1])),
1414            c(&[0, 3, 1, 0, 2])
1415        );
1416        assert_eq!(
1417            c(&[2, 0, 3, 1, 4]).update_from_simplified(c(&[3, 1, 4, 2, 5])),
1418            c(&[3, 1, 4, 2, 5])
1419        );
1420
1421        assert_eq!(c(&[0, 0, 3, 1, 3, 2, 4]).simplify(), c(&[3, 1, 3, 2, 4]));
1422        // Check that the `3`s are replaced correctly and that `4` ends up in the
1423        // correct position.
1424        assert_eq!(
1425            c(&[0, 0, 3, 1, 3, 2, 4]).update_from_simplified(c(&[10, 1, 11, 2, 4])),
1426            c(&[0, 0, 10, 1, 11, 2, 4])
1427        );
1428    }
1429
1430    #[test]
1431    fn test_merge_invariants() {
1432        fn check_invariants(terms: &[u32]) {
1433            let merge = Merge::from_vec(terms.to_vec());
1434            // `simplify()` is idempotent
1435            assert_eq!(
1436                merge.simplify().simplify(),
1437                merge.simplify(),
1438                "simplify() not idempotent for {merge:?}"
1439            );
1440            // `resolve_trivial()` is unaffected by `simplify()`
1441            assert_eq!(
1442                merge.simplify().resolve_trivial(SameChange::Accept),
1443                merge.resolve_trivial(SameChange::Accept),
1444                "simplify() changed result of resolve_trivial() for {merge:?}"
1445            );
1446        }
1447        // 1-way merge
1448        check_invariants(&[0]);
1449        for i in 0..=1 {
1450            for j in 0..=i + 1 {
1451                // 3-way merge
1452                check_invariants(&[i, 0, j]);
1453                for k in 0..=j + 1 {
1454                    for l in 0..=k + 1 {
1455                        // 5-way merge
1456                        check_invariants(&[0, i, j, k, l]);
1457                    }
1458                }
1459            }
1460        }
1461    }
1462
1463    #[test]
1464    fn test_swap_remove() {
1465        let mut x = c(&[0, 1, 2, 3, 4, 5, 6]);
1466        assert_eq!(x.swap_remove(0, 1), (1, 2));
1467        assert_eq!(x, c(&[0, 5, 6, 3, 4]));
1468        assert_eq!(x.swap_remove(1, 0), (3, 0));
1469        assert_eq!(x, c(&[4, 5, 6]));
1470        assert_eq!(x.swap_remove(0, 1), (5, 6));
1471        assert_eq!(x, c(&[4]));
1472    }
1473
1474    #[test]
1475    fn test_pad_to() {
1476        let mut x = c(&[1]);
1477        x.pad_to(3, &2);
1478        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1479        // No change if the requested size is smaller
1480        x.pad_to(1, &3);
1481        assert_eq!(x, c(&[1, 2, 2, 2, 2]));
1482    }
1483
1484    #[test]
1485    fn test_iter() {
1486        // 1-way merge
1487        assert_eq!(c(&[1]).iter().collect_vec(), vec![&1]);
1488        // 5-way merge
1489        assert_eq!(
1490            c(&[1, 2, 3, 4, 5]).iter().collect_vec(),
1491            vec![&1, &2, &3, &4, &5]
1492        );
1493    }
1494
1495    #[test]
1496    fn test_from_iter() {
1497        // 1-way merge
1498        assert_eq!(MergeBuilder::from_iter([1]).build(), c(&[1]));
1499        // 5-way merge
1500        assert_eq!(
1501            MergeBuilder::from_iter([1, 2, 3, 4, 5]).build(),
1502            c(&[1, 2, 3, 4, 5])
1503        );
1504    }
1505
1506    #[test]
1507    #[should_panic]
1508    fn test_from_iter_empty() {
1509        MergeBuilder::from_iter([1; 0]).build();
1510    }
1511
1512    #[test]
1513    #[should_panic]
1514    fn test_from_iter_even() {
1515        MergeBuilder::from_iter([1, 2]).build();
1516    }
1517
1518    #[test]
1519    fn test_extend() {
1520        // 1-way merge
1521        let mut builder: MergeBuilder<i32> = Default::default();
1522        builder.extend([1]);
1523        assert_eq!(builder.build(), c(&[1]));
1524        // 5-way merge
1525        let mut builder: MergeBuilder<i32> = Default::default();
1526        builder.extend([1, 2]);
1527        builder.extend([3, 4, 5]);
1528        assert_eq!(builder.build(), c(&[1, 2, 3, 4, 5]));
1529    }
1530
1531    #[test]
1532    fn test_map() {
1533        fn increment(i: &i32) -> i32 {
1534            i + 1
1535        }
1536        // 1-way merge
1537        assert_eq!(c(&[1]).map(increment), c(&[2]));
1538        // 3-way merge
1539        assert_eq!(c(&[1, 3, 5]).map(increment), c(&[2, 4, 6]));
1540    }
1541
1542    #[test]
1543    fn test_try_map() {
1544        fn sqrt(i: &i32) -> Result<i32, ()> {
1545            if *i >= 0 {
1546                Ok(f64::from(*i).sqrt() as i32)
1547            } else {
1548                Err(())
1549            }
1550        }
1551        // 1-way merge
1552        assert_eq!(c(&[1]).try_map(sqrt), Ok(c(&[1])));
1553        assert_eq!(c(&[-1]).try_map(sqrt), Err(()));
1554        // 3-way merge
1555        assert_eq!(c(&[1, 4, 9]).try_map(sqrt), Ok(c(&[1, 2, 3])));
1556        assert_eq!(c(&[-1, 4, 9]).try_map(sqrt), Err(()));
1557        assert_eq!(c(&[1, -4, 9]).try_map(sqrt), Err(()));
1558    }
1559
1560    #[test]
1561    fn test_flatten() {
1562        // 1-way merge of 1-way merge
1563        assert_eq!(c(&[c(&[0])]).flatten(), c(&[0]));
1564        // 1-way merge of 3-way merge
1565        assert_eq!(c(&[c(&[0, 1, 2])]).flatten(), c(&[0, 1, 2]));
1566        // 3-way merge of 1-way merges
1567        assert_eq!(c(&[c(&[0]), c(&[1]), c(&[2])]).flatten(), c(&[0, 1, 2]));
1568        // 3-way merge of 3-way merges
1569        assert_eq!(
1570            c(&[c(&[0, 1, 2]), c(&[3, 4, 5]), c(&[6, 7, 8])]).flatten(),
1571            c(&[0, 1, 2, 5, 4, 3, 6, 7, 8])
1572        );
1573    }
1574
1575    #[test]
1576    fn test_zip() {
1577        // Zip of 1-way merges
1578        assert_eq!(c(&[1]).zip(c(&[2])), c(&[(1, 2)]));
1579        // Zip of 3-way merges
1580        assert_eq!(
1581            c(&[1, 2, 3]).zip(c(&[4, 5, 6])),
1582            c(&[(1, 4), (2, 5), (3, 6)])
1583        );
1584    }
1585
1586    #[test]
1587    fn test_unzip() {
1588        // 1-way merge
1589        assert_eq!(c(&[(1, 2)]).unzip(), (c(&[1]), c(&[2])));
1590        // 3-way merge
1591        assert_eq!(
1592            c(&[(1, 4), (2, 5), (3, 6)]).unzip(),
1593            (c(&[1, 2, 3]), c(&[4, 5, 6]))
1594        );
1595    }
1596}