ownable_core/traits/
mod.rs

1use alloc::borrow::Cow;
2use alloc::boxed::Box;
3use alloc::collections::BTreeMap;
4use core::borrow::Borrow;
5
6mod copy;
7mod iter;
8#[cfg(feature = "std")]
9mod std;
10
11/// Copy the structure and reference the original values.
12///
13/// This is always a deep copy of the structure.
14pub trait ToBorrowed<'a> {
15    /// Copy the structure and reference the original values.
16    ///
17    /// This is always a deep copy of the structure.
18    #[must_use]
19    fn to_borrowed(&'a self) -> Self;
20}
21
22/// Copy the structure and clone the original values.
23///
24/// This is always a deep copy.
25pub trait ToOwned {
26    /// The type after obtaining ownership, should be the same as before but with static lifetime.
27    type Owned;
28    /// Copy the structure and clone the original values.
29    ///
30    /// This is always a deep copy.
31    #[must_use]
32    fn to_owned(&self) -> Self::Owned;
33}
34
35/// Copy the structure and clone the original values if it's not owned.
36///
37/// This is always a deep copy of the structure.
38pub trait IntoOwned {
39    /// The type after obtaining ownership, should be the same as before but with static lifetime.
40    type Owned;
41    /// Copy the structure and clone the original values if it's not owned.
42    ///
43    /// This is always a deep copy of the structure.
44    #[must_use]
45    fn into_owned(self) -> Self::Owned;
46}
47
48// Cow
49
50impl<'a, T: alloc::borrow::ToOwned + ?Sized> ToBorrowed<'a> for Cow<'a, T> {
51    #[inline]
52    fn to_borrowed(&'a self) -> Self {
53        Cow::Borrowed(self.borrow())
54    }
55}
56
57impl<T: alloc::borrow::ToOwned + ?Sized + 'static> ToOwned for Cow<'_, T> {
58    type Owned = Cow<'static, T>;
59
60    #[inline]
61    fn to_owned(&self) -> Cow<'static, T> {
62        Cow::Owned(T::to_owned(self.borrow()))
63    }
64}
65
66impl<T: alloc::borrow::ToOwned + ?Sized + 'static> IntoOwned for Cow<'_, T> {
67    type Owned = Cow<'static, T>;
68
69    #[inline]
70    fn into_owned(self) -> Cow<'static, T> {
71        Cow::Owned(self.into_owned())
72    }
73}
74
75// Option
76
77impl<'a, T: ToBorrowed<'a>> ToBorrowed<'a> for Option<T> {
78    #[inline]
79    fn to_borrowed(&'a self) -> Self {
80        self.as_ref().map(ToBorrowed::to_borrowed)
81    }
82}
83
84impl<T: ToOwned> ToOwned for Option<T> {
85    type Owned = Option<T::Owned>;
86
87    #[inline]
88    fn to_owned(&self) -> Self::Owned {
89        self.as_ref().map(ToOwned::to_owned)
90    }
91}
92
93impl<T: IntoOwned> IntoOwned for Option<T> {
94    type Owned = Option<T::Owned>;
95
96    #[inline]
97    fn into_owned(self) -> Self::Owned {
98        self.map(IntoOwned::into_owned)
99    }
100}
101
102// Box<T>
103
104impl<'a, T: ToBorrowed<'a>> ToBorrowed<'a> for Box<T> {
105    #[inline]
106    fn to_borrowed(&'a self) -> Self {
107        Box::new(self.as_ref().to_borrowed())
108    }
109}
110
111impl<T: ToOwned> ToOwned for Box<T> {
112    type Owned = Box<T::Owned>;
113
114    #[inline]
115    fn to_owned(&self) -> Self::Owned {
116        Box::new(self.as_ref().to_owned())
117    }
118}
119
120impl<T: IntoOwned> IntoOwned for Box<T> {
121    type Owned = Box<T::Owned>;
122
123    #[inline]
124    fn into_owned(self) -> Self::Owned {
125        Box::new((*self).into_owned())
126    }
127}
128
129// Box<[T]>
130
131impl<'a, T: ToBorrowed<'a>> ToBorrowed<'a> for Box<[T]> {
132    #[inline]
133    fn to_borrowed(&'a self) -> Self {
134        self.iter().map(ToBorrowed::to_borrowed).collect()
135    }
136}
137
138impl<T: ToOwned> ToOwned for Box<[T]> {
139    type Owned = Box<[T::Owned]>;
140
141    #[inline]
142    fn to_owned(&self) -> Self::Owned {
143        self.iter().map(ToOwned::to_owned).collect()
144    }
145}
146
147impl<T: IntoOwned> IntoOwned for Box<[T]> {
148    type Owned = Box<[T::Owned]>;
149
150    #[inline]
151    fn into_owned(self) -> Self::Owned {
152        self.into_vec()
153            .into_iter()
154            .map(IntoOwned::into_owned)
155            .collect()
156    }
157}
158
159// BTreeMap
160
161impl<'a, K, V> ToBorrowed<'a> for BTreeMap<K, V>
162where
163    K: ToBorrowed<'a> + Ord,
164    V: ToBorrowed<'a>,
165{
166    #[inline]
167    fn to_borrowed(&'a self) -> Self {
168        self.iter()
169            .map(|(k, v)| (ToBorrowed::to_borrowed(k), ToBorrowed::to_borrowed(v)))
170            .collect()
171    }
172}
173
174impl<K, V> ToOwned for BTreeMap<K, V>
175where
176    K: ToOwned,
177    <K as ToOwned>::Owned: Ord,
178    V: ToOwned,
179{
180    type Owned = BTreeMap<K::Owned, V::Owned>;
181
182    #[inline]
183    fn to_owned(&self) -> Self::Owned where {
184        self.iter()
185            .map(|(k, v)| (ToOwned::to_owned(k), ToOwned::to_owned(v)))
186            .collect()
187    }
188}
189
190impl<K, V> IntoOwned for BTreeMap<K, V>
191where
192    K: IntoOwned,
193    <K as IntoOwned>::Owned: Ord,
194    V: IntoOwned,
195{
196    type Owned = BTreeMap<K::Owned, V::Owned>;
197
198    #[inline]
199    fn into_owned(self) -> Self::Owned {
200        self.into_iter()
201            .map(|(k, v)| (IntoOwned::into_owned(k), IntoOwned::into_owned(v)))
202            .collect()
203    }
204}
205
206// Arrays
207
208impl<'a, T, const N: usize> ToBorrowed<'a> for [T; N]
209where
210    T: ToBorrowed<'a>,
211{
212    #[inline]
213    fn to_borrowed(&'a self) -> Self {
214        core::array::from_fn(|i| self[i].to_borrowed())
215    }
216}
217
218impl<T, const N: usize> ToOwned for [T; N]
219where
220    T: ToOwned,
221{
222    type Owned = [T::Owned; N];
223
224    #[inline]
225    fn to_owned(&self) -> Self::Owned {
226        core::array::from_fn(|i| self[i].to_owned())
227    }
228}
229
230impl<T, const N: usize> IntoOwned for [T; N]
231where
232    T: IntoOwned,
233{
234    type Owned = [T::Owned; N];
235
236    #[inline]
237    fn into_owned(self) -> Self::Owned {
238        self.map(IntoOwned::into_owned)
239    }
240}
241
242// Tuples
243
244macro_rules! tuple_impls {
245    ($($(#[$attrs:meta])?($($n:tt $name:ident)+),)+) => {
246        $(
247            impl<'a, $($name: ToBorrowed<'a>),+> ToBorrowed<'a> for ($($name,)+) {
248                $(#[$attrs])?
249                fn to_borrowed(&'a self) -> Self {
250                    ($(self.$n.to_borrowed(),)+)
251                }
252            }
253
254            impl<$($name: ToOwned),+> ToOwned for ($($name,)+) {
255                type Owned = ($($name::Owned,)+);
256
257                $(#[$attrs])?
258                fn to_owned(&self) -> Self::Owned where {
259                    ($(self.$n.to_owned(),)+)
260                }
261            }
262
263            impl<$($name: IntoOwned),+> IntoOwned for ($($name,)+) {
264                type Owned = ($($name::Owned,)+);
265
266                $(#[$attrs])?
267                fn into_owned(self) -> Self::Owned {
268                    ($(IntoOwned::into_owned(self.$n),)+)
269                }
270            }
271        )+
272    };
273}
274
275tuple_impls! {
276    #[inline(always)] (0 T0),
277    #[inline] (0 T0 1 T1),
278    #[inline] (0 T0 1 T1 2 T2),
279    (0 T0 1 T1 2 T2 3 T3),
280    (0 T0 1 T1 2 T2 3 T3 4 T4),
281    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5),
282    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6),
283    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7),
284    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8),
285    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9),
286    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10),
287    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11),
288    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12),
289    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13),
290    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14),
291    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15),
292}