1pub use static_self_derive::IntoOwned;
2
3pub trait IntoOwned<'any> {
7 type Owned: 'any;
9
10 fn into_owned(self) -> Self::Owned;
12}
13
14macro_rules! impl_into_owned {
15 ($t: ty) => {
16 impl<'a> IntoOwned<'a> for $t {
17 type Owned = Self;
18
19 #[inline]
20 fn into_owned(self) -> Self {
21 self
22 }
23 }
24 };
25 ($($t:ty),*) => {
26 $(impl_into_owned!($t);)*
27 };
28}
29
30impl_into_owned!(bool, f32, f64, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize, char, String);
31
32macro_rules! impl_tuple {
33 (
34 $($name:ident),*
35 ) =>{
36 #[allow(non_snake_case)]
37 impl<'any, $($name,)*> IntoOwned<'any> for ($($name,)*)
38 where
39 $($name: IntoOwned<'any>),*
40 {
41 type Owned = ($(<$name as IntoOwned<'any>>::Owned,)*);
42
43 #[inline]
44 fn into_owned(self) -> Self::Owned {
45 let ($($name,)*) = self;
46 ($($name.into_owned(),)*)
47 }
48 }
49 };
50}
51
52macro_rules! call_impl_tuple {
53 () => {};
54 ($first:ident) => {
55 impl_tuple!($first);
56 };
57 (
58 $first:ident,
59 $($name:ident),*
60 ) => {
61 call_impl_tuple!($($name),*);
62 impl_tuple!($first, $($name),*);
63 };
64}
65
66call_impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
67
68impl<'any, T> IntoOwned<'any> for Vec<T>
69where
70 T: IntoOwned<'any>,
71{
72 type Owned = Vec<<T as IntoOwned<'any>>::Owned>;
73
74 fn into_owned(self) -> Self::Owned {
75 self.into_iter().map(|v| v.into_owned()).collect()
76 }
77}
78impl<'any, T> IntoOwned<'any> for Option<T>
79where
80 T: IntoOwned<'any>,
81{
82 type Owned = Option<<T as IntoOwned<'any>>::Owned>;
83
84 fn into_owned(self) -> Self::Owned {
85 self.map(|v| v.into_owned())
86 }
87}
88
89impl<'any, T> IntoOwned<'any> for Box<T>
90where
91 T: IntoOwned<'any>,
92{
93 type Owned = Box<<T as IntoOwned<'any>>::Owned>;
94
95 fn into_owned(self) -> Self::Owned {
96 Box::new((*self).into_owned())
97 }
98}
99
100impl<'any, T> IntoOwned<'any> for Box<[T]>
101where
102 T: IntoOwned<'any>,
103{
104 type Owned = Box<[<T as IntoOwned<'any>>::Owned]>;
105
106 fn into_owned(self) -> Self::Owned {
107 self.into_vec().into_owned().into_boxed_slice()
108 }
109}
110
111#[cfg(feature = "smallvec")]
112impl<'any, T, const N: usize> IntoOwned<'any> for smallvec::SmallVec<[T; N]>
113where
114 T: IntoOwned<'any>,
115 [T; N]: smallvec::Array<Item = T>,
116 [<T as IntoOwned<'any>>::Owned; N]: smallvec::Array<Item = <T as IntoOwned<'any>>::Owned>,
117{
118 type Owned = smallvec::SmallVec<[<T as IntoOwned<'any>>::Owned; N]>;
119
120 fn into_owned(self) -> Self::Owned {
121 self.into_iter().map(|v| v.into_owned()).collect()
122 }
123}
124
125#[cfg(feature = "indexmap")]
126impl<'any, K, V> IntoOwned<'any> for indexmap::IndexMap<K, V>
127where
128 K: IntoOwned<'any>,
129 V: IntoOwned<'any>,
130 <K as IntoOwned<'any>>::Owned: Eq + std::hash::Hash,
131{
132 type Owned = indexmap::IndexMap<<K as IntoOwned<'any>>::Owned, <V as IntoOwned<'any>>::Owned>;
133
134 fn into_owned(self) -> Self::Owned {
135 self.into_iter().map(|(k, v)| (k.into_owned(), v.into_owned())).collect()
136 }
137}
138
139impl<'any, T, const N: usize> IntoOwned<'any> for [T; N]
140where
141 T: IntoOwned<'any>,
142{
143 type Owned = [<T as IntoOwned<'any>>::Owned; N];
144
145 fn into_owned(self) -> Self::Owned {
146 self
147 .into_iter()
148 .map(|v| v.into_owned())
149 .collect::<Vec<_>>()
150 .try_into()
151 .unwrap_or_else(|_| unreachable!("Vec<T> with N elements should be able to be converted to [T; N]"))
152 }
153}