1#![no_std]
13use core::ops::{Index, IndexMut};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct Slice2D<'t, T> {
18 stride: usize,
19 len: usize,
20 slice: &'t [T],
21}
22
23#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct Slice2DMut<'t, T> {
26 stride: usize,
27 len: usize,
28 slice: &'t mut [T],
29}
30
31impl<T> Slice2D<'_, T> {
32 pub fn get(&self, index: usize) -> Option<&[T]> {
34 let origin = index * self.stride;
35 self.slice.get(origin..origin + self.len)
36 }
37}
38
39impl<'t, T> Slice2DMut<'t, T> {
40 pub fn downgrade(&self) -> Slice2D<'_, T> {
42 Slice2D {
43 stride: self.stride,
44 len: self.len,
45 slice: self.slice,
46 }
47 }
48
49 pub fn reborrow(&mut self) -> Slice2DMut<'_, T> {
51 Slice2DMut {
52 stride: self.stride,
53 len: self.len,
54 slice: self.slice,
55 }
56 }
57
58 pub fn get(&self, index: usize) -> Option<&[T]> {
60 let origin = index * self.stride;
61 self.slice.get(origin..origin + self.len)
62 }
63
64 pub fn get_mut(&mut self, index: usize) -> Option<&mut [T]> {
66 let origin = index * self.stride;
67 self.slice.get_mut(origin..origin + self.len)
68 }
69}
70
71impl<T> Index<usize> for Slice2D<'_, T> {
72 type Output = [T];
73
74 fn index(&self, index: usize) -> &Self::Output {
75 let origin = index * self.stride;
76 &self.slice[origin..origin + self.len]
77 }
78}
79
80impl<T> Index<usize> for Slice2DMut<'_, T> {
81 type Output = [T];
82
83 fn index(&self, index: usize) -> &Self::Output {
84 let origin = index * self.stride;
85 &self.slice[origin..origin + self.len]
86 }
87}
88
89impl<T> IndexMut<usize> for Slice2DMut<'_, T> {
90 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
91 let origin = index * self.stride;
92 &mut self.slice[origin..origin + self.len]
93 }
94}
95
96impl<'t, T> Iterator for Slice2D<'t, T> {
97 type Item = &'t [T];
98
99 fn next(&mut self) -> Option<Self::Item> {
100 let result = self.slice.get(0..self.len);
101 self.slice = self.slice.get(self.stride..).unwrap_or(&[]);
102 result
103 }
104}
105
106pub trait Slice2DExt {
108 type Item;
109
110 fn slice2d(&self, len: usize, stride: usize) -> Slice2D<'_, Self::Item>;
114 fn slice2d_mut(&mut self, len: usize, stride: usize) -> Slice2DMut<'_, Self::Item>;
118
119 fn get_slice2d(&self, x: usize, y: usize) -> Option<Slice2D<'_, Self::Item>>;
123 fn get_slice2d_mut(&mut self, x: usize, y: usize) -> Option<Slice2DMut<'_, Self::Item>>;
127}
128
129impl<T> Slice2DExt for [T] {
130 type Item = T;
131 fn slice2d(&self, len: usize, stride: usize) -> Slice2D<'_, Self::Item> {
132 Slice2D {
133 len,
134 stride,
135 slice: self,
136 }
137 }
138
139 fn slice2d_mut(&mut self, len: usize, stride: usize) -> Slice2DMut<'_, Self::Item> {
140 Slice2DMut {
141 len,
142 stride,
143 slice: self,
144 }
145 }
146
147 fn get_slice2d(&self, x: usize, y: usize) -> Option<Slice2D<'_, Self::Item>> {
148 if self.len() != x * y {
149 return None;
150 }
151 Some(Slice2D {
152 len: y,
153 stride: y,
154 slice: self,
155 })
156 }
157
158 fn get_slice2d_mut(&mut self, x: usize, y: usize) -> Option<Slice2DMut<'_, Self::Item>> {
159 if self.len() != x * y {
160 return None;
161 }
162 Some(Slice2DMut {
163 len: y,
164 stride: y,
165 slice: self,
166 })
167 }
168}
169
170#[cfg(test)]
171mod test {
172 pub use crate::Slice2DExt;
173
174 #[test]
175 fn test() {
176 let v = [1, 2, 3, 4, 5, 6, 7, 8, 9];
177 let mut slice = v.get_slice2d(3, 3).unwrap();
178 assert_eq!(slice[0][0], 1);
179 assert_eq!(slice[0][1], 2);
180 assert_eq!(slice[0][2], 3);
181 assert_eq!(slice[1][0], 4);
182 assert_eq!(slice[1][1], 5);
183 assert_eq!(slice[1][2], 6);
184 assert_eq!(slice[2][0], 7);
185 assert_eq!(slice[2][1], 8);
186 assert_eq!(slice[2][2], 9);
187 assert_eq!(&slice[1], &[4, 5, 6]);
188
189 assert_eq!(slice.next().unwrap(), &[1, 2, 3]);
190 assert_eq!(slice.next().unwrap(), &[4, 5, 6]);
191 assert_eq!(slice.next().unwrap(), &[7, 8, 9]);
192 assert_eq!(slice.next(), None);
193 assert_eq!(slice.next(), None);
194
195 let mut v = [1, 2, 3, 4, 5, 6];
196 let slice = v.get_slice2d_mut(3, 2).unwrap();
197 assert_eq!(slice[0][0], 1);
198 assert_eq!(slice[0][1], 2);
199 assert_eq!(slice[1][0], 3);
200 assert_eq!(slice[1][1], 4);
201 assert_eq!(slice[2][0], 5);
202 assert_eq!(slice[2][1], 6);
203 assert_eq!(&slice[1], &[3, 4]);
204 }
205}