devela/data/collections/vec/ext.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
// devela::data::collections::vec::ext
//
//!
//
use crate::Vec;
/// Marker trait to prevent downstream implementations of the [`ExtVec`] trait.
trait Sealed {}
impl<T> Sealed for Vec<T> {}
/// Extension trait providing additional methods for [`Vec`].
///
/// This trait is sealed and cannot be implemented for any other type.
#[cfg_attr(feature = "nightly_doc", doc(notable_trait))]
#[expect(private_bounds, reason = "Sealed")]
pub trait ExtVec<T>: Sealed {
/* convert */
/// Converts `Vec<T>` to `Vec<U>` when `U` implements `From<T>`.
/// # Examples
/// ```
/// # use devela::ExtVec;
/// assert_eq![vec![1_u16, 2, 3], vec![1_u8, 2, 3].vec_into_vec::<u16>()];
/// assert_eq![vec![1_u16, 2, 3], vec![1_u8, 2, 3].vec_into_vec::<u16>()];
/// ```
#[must_use]
fn vec_into_vec<U>(self) -> Vec<U>
where
U: From<T>;
/// Tries to convert `Vec<T>` to `Vec<U>` when `U` implements `TryFrom<T>`.
/// # Examples
/// ```
/// # use devela::ExtVec;
/// assert_eq![Ok(vec![1_i32, 2, 3]), vec![1_i64, 2, 3].vec_try_into_vec()];
/// assert_eq![Ok(vec![1_i32, 2, 3]), vec![1_i64, 2, 3].vec_try_into_vec::<_, i32>()];
/// ```
fn vec_try_into_vec<E, U>(self) -> Result<Vec<U>, E>
where
U: TryFrom<T, Error = E>;
}
impl<T> ExtVec<T> for Vec<T> {
/* convert */
#[rustfmt::skip]
fn vec_into_vec<U>(self) -> Vec<U> where U: From<T> {
self.into_iter().map(|t| U::from(t)).collect::<Vec<_>>().into_iter().collect()
}
#[rustfmt::skip]
fn vec_try_into_vec<E, U>(self) -> Result<Vec<U>, E> where U: TryFrom<T, Error = E> {
self.into_iter()
// 1. Vec<Result<_>>:
.map(U::try_from)
.collect::<Vec<_>>()
// 2. Result<Vec<_>>:
.into_iter()
.collect::<Result<Vec<_>, _>>()
}
}