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 + (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}