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        fn as_slice(&self) -> &[Self::Item];
59        fn as_mut_slice(&mut self) -> &mut [Self::Item];
60        fn map<F, U>(self, f: F) -> impl Array<Item = U>
61        where
62            F: FnMut(Self::Item) -> U;
63        fn each_ref(&self) -> impl Array<Item = &Self::Item>;
64        fn each_mut(&mut self) -> impl Array<Item = &mut Self::Item>;
65    }
66);
67
68impl<const N: usize, T> Primitive for [T; N] {}
69impl<const N: usize, T> Array for [T; N] {
70    const N: usize = N;
71
72    fn as_slice(&self) -> &[Self::Item] {
73        self.as_slice()
74    }
75
76    fn as_mut_slice(&mut self) -> &mut [Self::Item] {
77        self.as_mut_slice()
78    }
79
80    fn map<F, U>(self, f: F) -> impl Array<Item = U>
81    where
82        F: FnMut(Self::Item) -> U,
83    {
84        self.map(f)
85    }
86
87    fn each_ref(&self) -> impl Array<Item = &Self::Item> {
88        self.each_ref()
89    }
90
91    fn each_mut(&mut self) -> impl Array<Item = &mut Self::Item> {
92        self.each_mut()
93    }
94}
95
96#[cfg(test)]
97mod test {
98    use super::*;
99
100    #[test]
101    fn test_index() {
102        fn first<T: Array>(v: &T) -> &T::Item {
103            &v[0]
104        }
105
106        assert_eq!(first(&[123, 456]), &123);
107    }
108
109    #[cfg(feature = "alloc")]
110    #[test]
111    fn test_to_vec() {
112        fn to_vec<T: Array>(v: T) -> alloc::vec::Vec<T::Item> {
113            v.into()
114        }
115
116        assert_eq!(to_vec([123, 456]), alloc::vec![123, 456]);
117    }
118}