Coverage Report

Created: 2024-12-17 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/yoke-0.7.5/src/either.rs
Line
Count
Source (jump to first uncovered line)
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
//! Types to enable polymorphic carts.
6
7
use crate::CloneableCart;
8
9
use core::ops::Deref;
10
use stable_deref_trait::StableDeref;
11
12
/// A cart that can be one type or the other. Enables ergonomic polymorphic carts.
13
///
14
/// `EitherCart` enables yokes originating from different data sources and therefore
15
/// having different cart types to be merged into the same yoke type, but still being
16
/// able to recover the original cart type if necessary.
17
///
18
/// All relevant Cart traits are implemented for `EitherCart`, and carts can be
19
/// safely wrapped in an `EitherCart`.
20
///
21
/// Also see [`Yoke::erase_box_cart()`](crate::Yoke::erase_box_cart).
22
///
23
/// # Examples
24
///
25
/// ```
26
/// use std::rc::Rc;
27
/// use yoke::either::EitherCart;
28
/// use yoke::Yoke;
29
///
30
/// let y1: Yoke<&'static str, Rc<str>> =
31
///     Yoke::attach_to_zero_copy_cart("reference counted hello world".into());
32
///
33
/// let y2: Yoke<&'static str, &str> = Yoke::attach_to_zero_copy_cart("borrowed hello world");
34
///
35
/// type CombinedYoke<'a> = Yoke<&'static str, EitherCart<Rc<str>, &'a str>>;
36
///
37
/// // Both yokes can be combined into a single yoke type despite different carts
38
/// let y3: CombinedYoke = y1.wrap_cart_in_either_a();
39
/// let y4: CombinedYoke = y2.wrap_cart_in_either_b();
40
///
41
/// assert_eq!(*y3.get(), "reference counted hello world");
42
/// assert_eq!(*y4.get(), "borrowed hello world");
43
///
44
/// // The resulting yoke is cloneable if both cart types implement CloneableCart
45
/// let y5 = y4.clone();
46
/// assert_eq!(*y5.get(), "borrowed hello world");
47
/// ```
48
#[derive(Clone, PartialEq, Eq, Debug)]
49
#[allow(clippy::exhaustive_enums)] // stable
50
pub enum EitherCart<C0, C1> {
51
    A(C0),
52
    B(C1),
53
}
54
55
impl<C0, C1, T> Deref for EitherCart<C0, C1>
56
where
57
    C0: Deref<Target = T>,
58
    C1: Deref<Target = T>,
59
{
60
    type Target = T;
61
0
    fn deref(&self) -> &T {
62
        use EitherCart::*;
63
0
        match self {
64
0
            A(a) => a.deref(),
65
0
            B(b) => b.deref(),
66
        }
67
0
    }
68
}
69
70
// Safety: Safe because both sub-types implement the trait.
71
unsafe impl<C0, C1, T> StableDeref for EitherCart<C0, C1>
72
where
73
    C0: StableDeref,
74
    C1: StableDeref,
75
    C0: Deref<Target = T>,
76
    C1: Deref<Target = T>,
77
{
78
}
79
80
// Safety: Safe because both sub-types implement the trait.
81
unsafe impl<C0, C1> CloneableCart for EitherCart<C0, C1>
82
where
83
    C0: CloneableCart,
84
    C1: CloneableCart,
85
{
86
}