1use std::fmt;
2use std::ops::{Index, IndexMut};
3
4pub type Selector = (usize, usize);
6
7pub struct Matrix<T> {
9 data: Vec<T>,
10 width: usize,
11 height: usize,
12}
13
14impl<T> Matrix<T>
15where
16 T: Default + Clone,
17{
18 pub fn new(width: usize, height: usize) -> Self {
29 Matrix {
30 data: vec![T::default(); width * height],
31 width,
32 height,
33 }
34 }
35
36 fn get_index(&self, selector: Selector) -> Option<usize> {
46 let (y, x) = selector;
47 let index = y * self.width + x;
48
49 if index < self.width * self.height {
50 Some(index)
51 } else {
52 None
53 }
54 }
55
56 pub fn get(&self, selector: Selector) -> Option<&T> {
75 match self.get_index(selector) {
76 Some(index) => self.data.get(index),
77 None => None,
78 }
79 }
80
81 pub fn get_mut(&mut self, selector: Selector) -> Option<&mut T> {
100 match self.get_index(selector) {
101 Some(index) => self.data.get_mut(index),
102 None => None,
103 }
104 }
105
106 pub fn width(&self) -> usize {
108 self.width
109 }
110
111 pub fn height(&self) -> usize {
113 self.height
114 }
115}
116
117impl<T> Index<Selector> for Matrix<T>
118where
119 T: Default + Clone,
120{
121 type Output = T;
122
123 fn index(&self, selector: Selector) -> &Self::Output {
135 self.get(selector)
136 .unwrap_or_else(|| panic!("Invalid index ({}, {})", selector.0, selector.1))
137 }
138}
139
140impl<T> IndexMut<Selector> for Matrix<T>
141where
142 T: Default + Clone,
143{
144 fn index_mut(&mut self, selector: Selector) -> &mut Self::Output {
156 self.get_mut(selector)
157 .unwrap_or_else(|| panic!("Invalid index ({}, {})", selector.0, selector.1))
158 }
159}
160
161impl<T> fmt::Display for Matrix<T>
162where
163 T: Default + Clone + fmt::Display,
164{
165 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
167 for y in 0..self.height() {
168 for x in 0..self.width() - 1 {
169 write!(f, "{} ", self[(y, x)])?;
170 }
171 writeln!(f, "{}", self[(y, self.width() - 1)])?;
172 }
173
174 Ok(())
175 }
176}
177
178#[cfg(test)]
179mod test {
180 use super::*;
181
182 #[test]
183 fn test_get_index() {
184 let matrix: Matrix<u32> = Matrix::new(3, 3);
185
186 assert_eq!(matrix.get_index((0, 0)), Some(0));
187 assert_eq!(matrix.get_index((0, 1)), Some(1));
188 assert_eq!(matrix.get_index((0, 2)), Some(2));
189 assert_eq!(matrix.get_index((1, 0)), Some(3));
190 assert_eq!(matrix.get_index((1, 1)), Some(4));
191 assert_eq!(matrix.get_index((1, 2)), Some(5));
192 assert_eq!(matrix.get_index((2, 0)), Some(6));
193 assert_eq!(matrix.get_index((2, 1)), Some(7));
194 assert_eq!(matrix.get_index((2, 2)), Some(8));
195 }
196
197 #[test]
198 fn test_get() {
199 let matrix = Matrix::new(3, 3);
200 assert_eq!(matrix.get((1, 1)), Some(0).as_ref());
202 }
203
204 #[test]
205 fn test_get_mut() {
206 let mut matrix = Matrix::new(3, 3);
207 if let Some(reference) = matrix.get_mut((1, 0)) {
208 *reference = 112;
209 }
210
211 assert_eq!(matrix.get((1, 0)), Some(112).as_ref());
212 }
213
214 #[test]
215 fn test_index() {
216 let matrix = Matrix::<u32>::new(3, 3);
217 assert_eq!(matrix[(1, 1)], 0u32);
219 }
220
221 #[test]
222 fn test_index_mut() {
223 let mut matrix = Matrix::<u32>::new(3, 3);
224 matrix[(1, 1)] = 112;
225
226 assert_eq!(matrix[(1, 1)], 112u32);
227 }
228}