pub use static_self_derive::IntoOwned;
pub trait IntoOwned<'any> {
type Owned: 'any;
fn into_owned(self) -> Self::Owned;
}
macro_rules! impl_into_owned {
($t: ty) => {
impl<'a> IntoOwned<'a> for $t {
type Owned = Self;
#[inline]
fn into_owned(self) -> Self {
self
}
}
};
($($t:ty),*) => {
$(impl_into_owned!($t);)*
};
}
impl_into_owned!(bool, f32, f64, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize, char, String);
macro_rules! impl_tuple {
(
$($name:ident),*
) =>{
#[allow(non_snake_case)]
impl<'any, $($name,)*> IntoOwned<'any> for ($($name,)*)
where
$($name: IntoOwned<'any>),*
{
type Owned = ($(<$name as IntoOwned<'any>>::Owned,)*);
#[inline]
fn into_owned(self) -> Self::Owned {
let ($($name,)*) = self;
($($name.into_owned(),)*)
}
}
};
}
macro_rules! call_impl_tuple {
() => {};
($first:ident) => {
impl_tuple!($first);
};
(
$first:ident,
$($name:ident),*
) => {
call_impl_tuple!($($name),*);
impl_tuple!($first, $($name),*);
};
}
call_impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
impl<'any, T> IntoOwned<'any> for Vec<T>
where
T: IntoOwned<'any>,
{
type Owned = Vec<<T as IntoOwned<'any>>::Owned>;
fn into_owned(self) -> Self::Owned {
self.into_iter().map(|v| v.into_owned()).collect()
}
}
impl<'any, T> IntoOwned<'any> for Option<T>
where
T: IntoOwned<'any>,
{
type Owned = Option<<T as IntoOwned<'any>>::Owned>;
fn into_owned(self) -> Self::Owned {
self.map(|v| v.into_owned())
}
}
impl<'any, T> IntoOwned<'any> for Box<T>
where
T: IntoOwned<'any>,
{
type Owned = Box<<T as IntoOwned<'any>>::Owned>;
fn into_owned(self) -> Self::Owned {
Box::new((*self).into_owned())
}
}
impl<'any, T> IntoOwned<'any> for Box<[T]>
where
T: IntoOwned<'any>,
{
type Owned = Box<[<T as IntoOwned<'any>>::Owned]>;
fn into_owned(self) -> Self::Owned {
self.into_vec().into_owned().into_boxed_slice()
}
}
#[cfg(feature = "smallvec")]
impl<'any, T, const N: usize> IntoOwned<'any> for smallvec::SmallVec<[T; N]>
where
T: IntoOwned<'any>,
[T; N]: smallvec::Array<Item = T>,
[<T as IntoOwned<'any>>::Owned; N]: smallvec::Array<Item = <T as IntoOwned<'any>>::Owned>,
{
type Owned = smallvec::SmallVec<[<T as IntoOwned<'any>>::Owned; N]>;
fn into_owned(self) -> Self::Owned {
self.into_iter().map(|v| v.into_owned()).collect()
}
}
impl<'any, T, const N: usize> IntoOwned<'any> for [T; N]
where
T: IntoOwned<'any>,
{
type Owned = [<T as IntoOwned<'any>>::Owned; N];
fn into_owned(self) -> Self::Owned {
self
.into_iter()
.map(|v| v.into_owned())
.collect::<Vec<_>>()
.try_into()
.unwrap_or_else(|_| unreachable!("Vec<T> with N elements should be able to be converted to [T; N]"))
}
}