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 #[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}