Skip to main content

std_traits/
array.rs

1use core::{
2    borrow::{Borrow, BorrowMut},
3    ops::{
4        Bound, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
5        RangeToInclusive,
6    },
7};
8
9use crate::primitive::Primitive;
10
11macro_rules! array_trait {
12    (($($bounds:tt +)*); ($($alloc_bounds:tt +)*) $impl:tt) => {
13        #[cfg(not(feature = "alloc"))]
14        pub trait Array: $($bounds +)* $impl
15
16        #[cfg(feature = "alloc")]
17        pub trait Array: $($bounds +)* $($alloc_bounds +)* $impl
18    }
19}
20
21array_trait!(
22    (
23        Primitive
24        + Sized
25        + IntoIterator // Contains `Self::Item`
26        + (AsRef<[Self::Item]>)
27        + (AsMut<[Self::Item]>)
28        + (Borrow<[Self::Item]>)
29        + (BorrowMut<[Self::Item]>)
30        + (Index<usize, Output = Self::Item>)
31        + (Index<(Bound<usize>, Bound<usize>), Output = [Self::Item]>)
32        + (Index<Range<usize>, Output = [Self::Item]>)
33        + (Index<RangeInclusive<usize>, Output = [Self::Item]>)
34        + (Index<RangeFrom<usize>, Output = [Self::Item]>)
35        + (Index<RangeTo<usize>, Output = [Self::Item]>)
36        + (Index<RangeToInclusive<usize>, Output = [Self::Item]>)
37        + (Index<RangeFull, Output = [Self::Item]>)
38        + (IndexMut<usize, Output = Self::Item>)
39        + (IndexMut<(Bound<usize>, Bound<usize>), Output = [Self::Item]>)
40        + (IndexMut<Range<usize>, Output = [Self::Item]>)
41        + (IndexMut<RangeInclusive<usize>, Output = [Self::Item]>)
42        + (IndexMut<RangeFrom<usize>, Output = [Self::Item]>)
43        + (IndexMut<RangeTo<usize>, Output = [Self::Item]>)
44        + (IndexMut<RangeToInclusive<usize>, Output = [Self::Item]>)
45        + (IndexMut<RangeFull, Output = [Self::Item]>)
46    +);
47    (
48        (TryFrom<alloc::vec::Vec<Self::Item>>)
49        + (Into<alloc::boxed::Box<[Self::Item]>>)
50        + (Into<alloc::rc::Rc<[Self::Item]>>)
51        + (Into<alloc::sync::Arc<[Self::Item]>>)
52        + (Into<alloc::vec::Vec<Self::Item>>)
53        + (Into<alloc::collections::VecDeque<Self::Item>>)
54        + (Into<alloc::collections::LinkedList<Self::Item>>)
55    +) {
56        const N: usize;
57
58        #[must_use]
59        fn as_slice(&self) -> &[Self::Item];
60        #[must_use]
61        fn as_mut_slice(&mut self) -> &mut [Self::Item];
62        #[must_use]
63        fn map<F, U>(self, f: F) -> impl Array<Item = U>
64        where
65            F: FnMut(Self::Item) -> U;
66        #[must_use]
67        fn each_ref(&self) -> impl Array<Item = &Self::Item>;
68        #[must_use]
69        fn each_mut(&mut self) -> impl Array<Item = &mut Self::Item>;
70    }
71);
72
73impl<const N: usize, T> Primitive for [T; N] {}
74impl<const N: usize, T> Array for [T; N] {
75    const N: usize = N;
76
77    fn as_slice(&self) -> &[Self::Item] {
78        self.as_slice()
79    }
80
81    fn as_mut_slice(&mut self) -> &mut [Self::Item] {
82        self.as_mut_slice()
83    }
84
85    fn map<F, U>(self, f: F) -> impl Array<Item = U>
86    where
87        F: FnMut(Self::Item) -> U,
88    {
89        self.map(f)
90    }
91
92    fn each_ref(&self) -> impl Array<Item = &Self::Item> {
93        self.each_ref()
94    }
95
96    fn each_mut(&mut self) -> impl Array<Item = &mut Self::Item> {
97        self.each_mut()
98    }
99}
100
101#[cfg(test)]
102mod test {
103    use super::*;
104
105    #[test]
106    fn test_index() {
107        fn first<T: Array>(v: &T) -> &T::Item {
108            &v[0]
109        }
110
111        assert_eq!(first(&[123, 456]), &123);
112    }
113
114    #[cfg(feature = "alloc")]
115    #[test]
116    fn test_to_vec() {
117        fn to_vec<T: Array>(v: T) -> alloc::vec::Vec<T::Item> {
118            v.into()
119        }
120
121        assert_eq!(to_vec([123, 456]), alloc::vec![123, 456]);
122    }
123}