tiny_vec/
cow.rs

1//! Cow implementation for TinyVec
2
3use core::fmt::Debug;
4use core::ops::Deref;
5
6#[cfg(feature = "alloc")]
7use alloc::{
8    boxed::Box,
9    vec::Vec
10};
11
12use crate::TinyVec;
13
14/// A Copy-on-Write struct for a TinyVec
15///
16/// This struct contains either a borrowed reference of `[T]`,
17/// or an owned TinyVec
18///
19/// # Example
20/// ```
21/// use tiny_vec::{TinyVec, Cow};
22///
23/// let vec = TinyVec::<i32, 5>::from([1, 2, 3, 4, 5]);
24/// let vec = Cow::from(vec);
25///
26/// assert_eq!(vec.as_slice(), &[1, 2, 3, 4, 5]);
27///
28/// let mut borrowed_cow = Cow::from(&vec);
29/// assert_eq!(borrowed_cow.as_slice(), &[1, 2, 3, 4, 5]);
30/// assert!(borrowed_cow.is_borrowed());
31///
32/// borrowed_cow.to_mut().push(6);
33/// assert_eq!(vec.as_slice(), &[1, 2, 3, 4, 5]);
34/// assert_eq!(borrowed_cow.as_slice(), &[1, 2, 3, 4, 5, 6]);
35/// assert!(borrowed_cow.is_owned());
36/// ```
37pub enum Cow<'borrow, T, const N: usize> {
38    Borrowed(&'borrow [T]),
39    Owned(TinyVec<T, N>),
40}
41
42impl<'borrow, T, const N: usize> Cow<'borrow, T, N> {
43    /// Converts this [Cow] into an [Owned](Cow::Owned) variant
44    pub fn to_owned(&mut self)
45    where
46        T: Clone
47    {
48        if let Cow::Borrowed(b) = self {
49            let tv = TinyVec::<T, N>::from_slice(b);
50            *self = Cow::Owned(tv)
51        }
52    }
53
54    /// Consumes this [Cow] and returns an [Owned](Cow::Owned) variant
55    pub fn into_owned(mut self) -> TinyVec<T, N>
56    where
57        T: Clone
58    {
59        self.to_owned();
60        match self {
61            Cow::Owned(w) => w,
62            Cow::Borrowed(_) => unreachable!("Self::to_owned must've turn self into an Owned variant"),
63        }
64    }
65
66    /// Gets a mutable reference to the [Owned] variant.
67    /// If this `Cow` is borrowed, it turns it into an [Owned]
68    /// variant first
69    ///
70    /// [Owned]: Cow::Owned
71    pub fn to_mut(&mut self) -> &mut TinyVec<T, N>
72    where
73        T: Clone
74    {
75        self.to_owned();
76        match self {
77            Cow::Owned(w) => w,
78            Cow::Borrowed(_) => unreachable!("Self::to_owned must've turn self into an Owned variant"),
79        }
80    }
81
82    /// Returns true if `self` is a [Borrowed](Cow::Borrowed) variant
83    pub const fn is_borrowed(&self) -> bool {
84        matches!(self, Cow::Borrowed(_))
85    }
86
87    /// Returns true if `self` is an [Owned](Cow::Owned) variant
88    pub const fn is_owned(&self) -> bool {
89        matches!(self, Cow::Owned(_))
90    }
91
92    /// Returns true if this [Cow] lives on the stack.
93    /// This is:
94    /// - It is a [Borrowed](Cow::Borrowed) variant
95    /// - It is an [Owned](Cow::Owned) variant that lives on the stack
96    pub const fn lives_on_stack(&self) -> bool {
97        match self {
98            Cow::Borrowed(_) => true,
99            Cow::Owned(v) => v.lives_on_stack(),
100        }
101    }
102
103    /// Returns `self` as a slice of T
104    pub const fn as_slice(&self) -> &[T] {
105        match self {
106            Cow::Borrowed(items) => items,
107            Cow::Owned(tiny_vec) => tiny_vec.as_slice()
108        }
109    }
110}
111
112impl<'borrow, T, const N: usize> Deref for Cow<'borrow, T, N> {
113    type Target = [T];
114
115    fn deref(&self) -> &Self::Target {
116        self.as_slice()
117    }
118}
119
120impl<'borrow, T, const N: usize> From<&'borrow [T]> for Cow<'borrow, T, N> {
121    fn from(value: &'borrow [T]) -> Self {
122        Self::Borrowed(value)
123    }
124}
125
126impl<'borrow, 'b2, T, const N: usize> From<&'b2 Cow<'borrow, T, N>> for Cow<'b2 , T, N> {
127    fn from(value: &'b2 Cow<'borrow, T, N>) -> Self {
128        Self::Borrowed(value.as_slice())
129    }
130}
131
132impl<'borrow, T, const N: usize, const M: usize> From<&'borrow [T; M]> for Cow<'borrow, T, N> {
133    fn from(value: &'borrow [T; M]) -> Self {
134        Self::Borrowed(value)
135    }
136}
137
138impl<'borrow, T, const N: usize> From<TinyVec<T, N>> for Cow<'borrow, T, N> {
139    fn from(value: TinyVec<T, N>) -> Self {
140        Self::Owned(value)
141    }
142}
143
144#[cfg(feature = "alloc")]
145impl<'borrow, T, const N: usize> From<Vec<T>> for Cow<'borrow, T, N> {
146    fn from(value: Vec<T>) -> Self {
147        Self::Owned(TinyVec::from(value))
148    }
149}
150
151#[cfg(feature = "alloc")]
152impl<'borrow, T, const N: usize> From<Box<[T]>> for Cow<'borrow, T, N> {
153    fn from(value: Box<[T]>) -> Self {
154        Self::Owned(TinyVec::from(value))
155    }
156}
157
158#[cfg(feature = "alloc")]
159impl<'borrow, T, const N: usize> From<&'borrow Vec<T>> for Cow<'borrow, T, N> {
160    fn from(value: &'borrow Vec<T>) -> Self {
161        Self::Borrowed(value)
162    }
163}
164
165#[cfg(feature = "alloc")]
166impl<'borrow, T, const N: usize> From<&'borrow Box<[T]>> for Cow<'borrow, T, N> {
167    fn from(value: &'borrow Box<[T]>) -> Self {
168        Self::Borrowed(value)
169    }
170}
171
172impl<'borrow, T: Debug, const N: usize> Debug for Cow<'borrow, T, N> {
173    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174        match self {
175            Self::Borrowed(arg0) => f.debug_tuple("Borrowed").field(arg0).finish(),
176            Self::Owned(arg0) => f.debug_tuple("Owned").field(arg0).finish(),
177        }
178    }
179}
180
181impl<'borrow, T: PartialEq, const N: usize> PartialEq for Cow<'borrow, T, N> {
182    fn eq(&self, other: &Self) -> bool {
183        match (self, other) {
184            (Self::Borrowed(l0), Self::Borrowed(r0)) => l0 == r0,
185            (Self::Owned(l0), Self::Owned(r0)) => l0 == r0,
186            _ => false,
187        }
188    }
189}
190
191impl<'borrow, T: Clone, const N: usize> Clone for Cow<'borrow, T, N> {
192    fn clone(&self) -> Self {
193        match self {
194            Self::Borrowed(arg0) => Self::Borrowed(arg0),
195            Self::Owned(arg0) => Self::Owned(arg0.clone()),
196        }
197    }
198}
199
200impl<'borrow, T, const N: usize> Default for Cow<'borrow, T, N> {
201    fn default() -> Self {
202        Self::Borrowed(&[])
203    }
204}