module/merge/mod.rs
1//! The [`Merge`] trait and utilities accompanying it.
2
3mod cell;
4mod context;
5mod error;
6mod impls;
7mod iter;
8mod trace;
9
10#[cfg(test)]
11mod tests;
12
13pub use self::cell::MergeCell;
14pub use self::context::Context;
15pub use self::error::{Error, ErrorKind};
16pub use self::iter::IteratorExt;
17pub use self::trace::{Trace, TraceIter};
18
19/// A value that may be merged.
20///
21/// This trait defines the interface by which 2 values are merged together.
22///
23/// There are 2 ways to merge values together only differing in whether they
24/// take ownership of the value.
25///
26/// * [`Merge::merge`]
27/// * [`Merge::merge_ref`]
28///
29/// Both of these methods must perform merging in the same way. Any deviation
30/// in the 2 implementations is considered undefined behavior and *will* lead
31/// to bugs.
32///
33/// [`Merge::merge`] is provided by default as long as you provide the
34/// implementation for [`Merge::merge_ref`]. Generally there should be no reason
35/// to have to implement both of the above.
36pub trait Merge: Sized {
37 /// Merge `self` with `other`.
38 ///
39 /// # Example
40 ///
41 /// ```rust
42 /// # use module::Merge;
43 /// let a = vec![1, 3, 4];
44 /// let b = vec![7, 2, 0];
45 ///
46 /// let c = a.merge(b).unwrap();
47 ///
48 /// assert_eq!(c, &[1, 3, 4, 7, 2, 0]);
49 /// ```
50 ///
51 /// # Implementation
52 ///
53 /// The default implementation of this method calls out to [`Merge::merge_ref`].
54 /// Don't implemenent this unless you can do something better.
55 fn merge(mut self, other: Self) -> Result<Self, Error> {
56 self.merge_ref(other)?;
57 Ok(self)
58 }
59
60 /// Merge `self` with `other` without taking ownership of `self`.
61 ///
62 /// # Example
63 ///
64 /// ```rust
65 /// # use module::Merge;
66 /// let mut a = vec![1, 3, 4];
67 /// let b = vec![7, 2, 0];
68 ///
69 /// a.merge_ref(b).unwrap();
70 ///
71 /// assert_eq!(a, &[1, 3, 4, 7, 2, 0]);
72 /// ```
73 fn merge_ref(&mut self, other: Self) -> Result<(), Error>;
74}
75
76/// Merge `this` and `other`.
77///
78/// Equivalent to: `this.merge(other)`.
79#[inline]
80pub fn merge<T>(this: T, other: T) -> Result<T, Error>
81where
82 T: Merge,
83{
84 this.merge(other)
85}