devela/data/list/array/vec/
ext.rs

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