1use std::ops::{Index, IndexMut};
8use vec2d_error::Vec2dError;
9use serde::{Serialize, Deserialize};
10pub mod vec2d_error;
11pub type Pos = (usize, usize);
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
14pub struct Vec2d<T: Clone> {
16 tiles: Vec<T>,
17 width: usize
18}
19
20impl<T: Clone> Index<Pos> for Vec2d<T> {
21 type Output = T;
22
23 fn index(&self, (x, y): Pos) -> &Self::Output {
24 if x >= self.width { panic!("Tried to index with x: {}, with width: {}", x, self.width) }
25 &self.tiles[y * self.width + x]
26 }
27}
28
29impl<T: Clone> IndexMut<Pos> for Vec2d<T> {
30 fn index_mut(&mut self, (x, y): Pos) -> &mut Self::Output {
31 if x >= self.width { panic!("Tried to index with x: {}, with width: {}", x, self.width) }
32 &mut self.tiles[y * self.width + x]
33 }
34}
35
36impl<T: Clone> Vec2d<T> {
37 pub fn new(default: T, width: usize, height: usize) -> Result<Vec2d<T>, Vec2dError> {
46 let no_tiles = width * height;
47 if no_tiles == 0 {
48 Err(Vec2dError::WidthOrHeightIs0{ width, height })
49 } else {
50 let mut tiles = Vec::with_capacity(no_tiles);
51 for _ in 1..no_tiles {
52 tiles.push(default.clone());
53 }
54 tiles.push(default);
55 Ok(Vec2d { tiles, width })
56 }
57 }
58
59 pub fn new_from_vec(input: Vec<T>, width: usize) -> Result<Vec2d<T>, Vec2dError> {
71 if input.len() == 0 || width == 0 {
72 Err(Vec2dError::WidthOrInputLenIs0{ input_len: input.len(), width })
73 } else if input.len() % width != 0 {
74 Err(Vec2dError::InputNotDivisibleByWidth{ input_len: input.len(), width })
75 } else {
76 Ok( Vec2d { tiles: input, width } )
77 }
78 }
79
80 pub fn for_each_tile<F: FnMut(&mut T)>(&mut self, fun: F) {
88 self.tiles.iter_mut().for_each(fun);
89 }
90
91 pub fn tiles(&self) -> &Vec<T> {
93 &self.tiles
94 }
95
96 pub fn height(&self) -> usize {
99 self.tiles.len() / self.width()
100 }
101
102 pub fn width(&self) -> usize {
105 self.width
106 }
107
108 pub fn get(&self, x: usize, y: usize) -> Option<&T> {
117 if x >= self.width { return None }
118 self.tiles.get(y * self.width + x)
119 }
120
121 pub fn get_mut(&mut self, x: usize, y: usize) -> Option<&mut T> {
130 if x >= self.width { return None }
131 self.tiles.get_mut(y * self.width + x)
132 }
133
134 pub fn get_row(&self, y: usize) -> Option<&[T]> {
135 if y >= self.tiles.len() / self.width { return None }
136 Some(&self.tiles[y * self.width .. (y+1) * self.width])
137 }
138
139 pub fn get_row_mut(&mut self, y: usize) -> Option<&mut [T]> {
140 if y >= self.tiles.len() / self.width { return None }
141 Some(&mut self.tiles[y * self.width .. (y+1) * self.width])
142 }
143
144 pub fn iter_xy(&self) -> impl Iterator<Item = (usize, impl Iterator<Item = usize>)> {
155 let width = self.width;
156 let height = self.height();
157 (0..width).map(move |i|(i, 0..height))
158 }
159
160 pub fn iter_rows(&self) -> impl Iterator<Item = &[T]> {
161 self.tiles
162 .rchunks(self.width)
163 .into_iter()
164 }
165
166 pub fn iter_rows_mut(&mut self) -> impl Iterator<Item = &mut [T]> {
167 self.tiles
168 .rchunks_mut(self.width)
169 .into_iter()
170 }
171
172 pub fn iter_with_pos<'a>(&'a self) -> impl Iterator<Item = (Pos, &T)> {
182 let width = self.width;
183 self.tiles.iter().enumerate().map(move |(nr, tile)| {
184 let x = nr % width;
185 let y = nr / width;
186 ((x, y), tile)
187 })
188 }
189
190 pub fn iter_with_pos_mut<'a>(&'a mut self) -> impl Iterator<Item = (Pos, &'a mut T)> {
200 let width = self.width;
201 self.tiles.iter_mut().enumerate().map(move |(nr, tile)| {
202 let x = nr % width;
203 let y = nr / width;
204 ((x, y), tile)
205 })
206 }
207
208 pub fn to_vec(self) -> Vec<T> {
217 self.tiles
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[test]
226 fn test_new() {
227 let board = Vec2d::new('a', 2, 2).unwrap();
228 assert_eq!(board,
229 Vec2d{
230 tiles: vec!['a', 'a', 'a', 'a'],
231 width: 2
232 }
233 );
234 let board = Vec2d::new(&'a', 0, 2);
235 assert!(board.is_err())
236 }
237
238 #[test]
239 fn test_get() {
240 let board = Vec2d::new('a', 2, 3).unwrap();
241 assert_eq!(board.get(1, 1), Some(&'a'));
242 assert_eq!(board.get(0, 0), Some(&'a'));
243 assert_eq!(board.get(1, 2), Some(&'a'));
244 assert_eq!(board.get(2, 2), None);
245 assert_eq!(board.get(1, 3), None);
246 }
247
248 #[test]
249 fn test_get_mut() {
250 let mut board = Vec2d::new('a', 2, 3).unwrap();
251 assert_eq!(board.get_mut(1, 1), Some(&mut 'a'));
252 assert_eq!(board.get_mut(0, 0), Some(&mut 'a'));
253 assert_eq!(board.get_mut(1, 2), Some(&mut 'a'));
254 assert_eq!(board.get_mut(2, 2), None);
255 assert_eq!(board.get_mut(1, 3), None);
256 }
257
258}