init_array/
array_ext.rs

1#[cfg(feature = "alloc")]
2use alloc::boxed::Box;
3
4use self::sealed::Sealed;
5
6mod sealed {
7    pub trait Sealed {}
8
9    impl<T, const N: usize> Sealed for [T; N] {}
10
11    impl<T> Sealed for [T] {}
12}
13
14/// Extension trait for constant sized arrays.
15///
16/// Allows you to initialize an array like this:
17/// ```
18/// use init_array::ArrayExt;
19///
20/// let arr: [usize; 5] = <[usize; 5]>::generate(|i| i * i);
21/// assert_eq!(arr, [0, 1, 4, 9, 16]);
22#[cfg_attr(feature = "alloc", doc = "")]
23#[cfg_attr(
24    feature = "alloc",
25    doc = "let arr: Box<[usize; 5]> = <[usize; 5]>::generate_boxed(|i| i * i);"
26)]
27#[cfg_attr(feature = "alloc", doc = "assert_eq!(arr, Box::new([0, 1, 4, 9, 16]));")]
28/// ```
29pub trait ArrayExt: Sealed {
30    type Elem;
31
32    fn generate<F: FnMut(usize) -> Self::Elem>(f: F) -> Self
33    where
34        Self: Sized;
35
36    fn try_generate<E, F: FnMut(usize) -> Result<Self::Elem, E>>(f: F) -> Result<Self, E>
37    where
38        Self: Sized;
39
40    #[cfg(feature = "alloc")]
41    fn generate_boxed<F: FnMut(usize) -> Self::Elem>(f: F) -> Box<Self>;
42}
43
44#[cfg(feature = "alloc")]
45/// Extension trait for dynamically sized slices.
46///
47/// Allows you to initialize a boxed slice like this:
48/// ```
49/// use init_array::SliceExt;
50///
51/// let arr: Box<[usize]> = <[usize]>::generate_boxed(5, |i| i * i);
52/// assert_eq!(&*arr, &[0, 1, 4, 9, 16]);
53/// ```
54pub trait SliceExt: Sealed {
55    type Elem;
56
57    fn generate_boxed<F: FnMut(usize) -> Self::Elem>(n: usize, f: F) -> Box<Self>;
58}
59
60impl<T, const N: usize> ArrayExt for [T; N] {
61    type Elem = T;
62
63    fn generate<F: FnMut(usize) -> Self::Elem>(f: F) -> Self
64    where
65        Self: Sized,
66    {
67        crate::init_array(f)
68    }
69
70    fn try_generate<E, F: FnMut(usize) -> Result<Self::Elem, E>>(f: F) -> Result<Self, E>
71    where
72        Self: Sized,
73    {
74        crate::try_init_array(f)
75    }
76
77    #[cfg(feature = "alloc")]
78    fn generate_boxed<F: FnMut(usize) -> Self::Elem>(f: F) -> Box<Self> {
79        crate::init_boxed_array(f)
80    }
81}
82
83#[cfg(feature = "alloc")]
84impl<T> SliceExt for [T] {
85    type Elem = T;
86
87    fn generate_boxed<F: FnMut(usize) -> Self::Elem>(n: usize, f: F) -> Box<Self> {
88        crate::init_boxed_slice(n, f)
89    }
90}