1#![no_std]
2#![forbid(unsafe_code)]
5
6pub trait SubArray {
51 type Item;
55
56 fn sub_array_ref<const N: usize>(&self, offset: usize) -> &[Self::Item; N];
72
73 fn sub_array_mut<const N: usize>(&mut self, offset: usize) -> &mut [Self::Item; N];
90}
91
92impl<T, const M: usize> SubArray for [T; M] {
94 type Item = T;
95
96 fn sub_array_ref<const N: usize>(&self, offset: usize) -> &[Self::Item; N] {
97 self[offset..(offset + N)].try_into().unwrap()
98 }
99
100 fn sub_array_mut<const N: usize>(&mut self, offset: usize) -> &mut [Self::Item; N] {
101 (&mut self[offset..(offset + N)]).try_into().unwrap()
102 }
103}
104
105impl<T> SubArray for [T] {
107 type Item = T;
108
109 fn sub_array_ref<const N: usize>(&self, offset: usize) -> &[Self::Item; N] {
110 self[offset..(offset + N)].try_into().unwrap()
111 }
112
113 fn sub_array_mut<const N: usize>(&mut self, offset: usize) -> &mut [Self::Item; N] {
114 (&mut self[offset..(offset + N)]).try_into().unwrap()
115 }
116}
117
118impl<T> SubArray for &mut T
120where
121 T: SubArray,
122{
123 type Item = T::Item;
124
125 fn sub_array_ref<const N: usize>(&self, offset: usize) -> &[Self::Item; N] {
126 (**self).sub_array_ref(offset)
127 }
128
129 fn sub_array_mut<const N: usize>(&mut self, offset: usize) -> &mut [Self::Item; N] {
130 (**self).sub_array_mut(offset)
131 }
132}
133
134
135
136#[cfg(test)]
137mod tests {
138 extern crate alloc;
139
140 use alloc::string::String;
141 use alloc::string::ToString;
142
143 use super::*;
144
145
146 #[test]
147 fn empty_ref() {
148 let arr = [0_u8; 0];
149 assert_eq!(arr.sub_array_ref::<0>(0), &[]);
150 }
151
152 #[test]
153 fn empty_mut() {
154 let mut arr = [0_u8; 0];
155 assert_eq!(arr.sub_array_mut::<0>(0), &mut []);
156 }
157
158 #[test]
159 fn full_ref() {
160 let arr = [1, 2, 3_i8];
161 assert_eq!(arr.sub_array_ref::<3>(0), &[1, 2, 3]);
162 }
163
164 #[test]
165 fn full_mut() {
166 let mut arr = [1, 2, 3_i8];
167 assert_eq!(arr.sub_array_mut::<3>(0), &mut [1, 2, 3]);
168 }
169
170 #[test]
171 fn first_ref() {
172 let arr = [1, 2, 3_u16];
173 assert_eq!(arr.sub_array_ref::<1>(0), &[1]);
174 }
175
176 #[test]
177 fn first_mut() {
178 let mut arr = [1, 2, 3_u16];
179 assert_eq!(arr.sub_array_mut::<1>(0), &mut [1]);
180 }
181
182 #[test]
183 fn middle_ref() {
184 let arr = [1, 2, 3_i16];
185 assert_eq!(arr.sub_array_ref::<1>(1), &[2]);
186 }
187
188 #[test]
189 fn middle_mut() {
190 let mut arr = [1, 2, 3_i16];
191 assert_eq!(arr.sub_array_mut::<1>(1), &mut [2]);
192 }
193
194 #[test]
195 fn last_ref() {
196 let arr = [1, 2, 3_i16];
197 assert_eq!(arr.sub_array_ref::<1>(2), &[3]);
198 }
199
200 #[test]
201 fn last_mut() {
202 let mut arr = [1, 2, 3_i16];
203 assert_eq!(arr.sub_array_mut::<1>(2), &mut [3]);
204 }
205
206 #[derive(Debug, PartialEq, Eq)]
207 struct NotClone(&'static str);
208
209 const NOT_CLONE_ARRAY: [NotClone; 5] = [
210 NotClone("abc"),
211 NotClone("foo"),
212 NotClone("bar"),
213 NotClone("qux"),
214 NotClone("fox"),
215 ];
216
217 #[test]
218 fn not_clone_ref() {
219 let exp_arr = [NotClone("foo"), NotClone("bar"), NotClone("qux")];
220 let arr = NOT_CLONE_ARRAY;
221 assert_eq!(arr.sub_array_ref::<3>(1), &exp_arr);
222 }
223
224 #[test]
225 fn not_clone_mut() {
226 let mut exp_arr = [NotClone("foo"), NotClone("bar"), NotClone("qux")];
227 let mut arr = NOT_CLONE_ARRAY;
228 assert_eq!(arr.sub_array_mut::<3>(1), &mut exp_arr);
229 }
230
231 #[test]
232 fn some_strings() {
233 let arr: [String; 5] = NOT_CLONE_ARRAY.map(|s| s.0.to_string());
234 assert_eq!(
235 arr.sub_array_ref::<2>(2),
236 &[String::from("bar"), String::from("qux")]
237 );
238 }
239
240 fn test_by_slice(s: &[u8]) -> &[u8; 3] {
241 s.sub_array_ref(4)
242 }
243
244 #[test]
245 fn slices() {
246 let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9_u8];
247
248 let slice: &[u8] = &arr;
249
250 let arr_ref = test_by_slice(slice);
251
252 assert_eq!(arr_ref, &[5, 6, 7]);
253 assert_eq!(arr_ref, arr.sub_array_ref(4));
254 assert_eq!(arr_ref, &slice[4..7]);
255 }
256}