1use std::mem;
45use std::ops::{Add, Index, IndexMut, Mul, Sub};
46pub const UP: Point = Point { x: 0, y: -1 };
47pub const DOWN: Point = Point { x: 0, y: 1 };
48pub const LEFT: Point = Point { x: -1, y: 0 };
49pub const RIGHT: Point = Point { x: 1, y: 0 };
50pub const UP_LEFT: Point = Point { x: -1, y: -1 };
51pub const UP_RIGHT: Point = Point { x: 1, y: -1 };
52pub const DOWN_LEFT: Point = Point { x: -1, y: 1 };
53pub const DOWN_RIGHT: Point = Point { x: 1, y: 1 };
54
55
56#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
57pub struct Point {
58 pub x: isize,
59 pub y: isize,
60}
61
62impl Point {
63 fn new(x: isize, y: isize) -> Point {
64 Point {x, y}
65 }
66}
67
68impl Add for Point {
69 type Output = Point;
70
71 fn add(self, other: Point) -> Point {
72 Point::new(self.x + other.x, self.y + other.y)
73 }
74}
75
76impl Sub for Point {
77 type Output = Point;
78
79 fn sub(self, other: Point) -> Point {
80 Point::new(self.x - other.x, self.y - other.y)
81 }
82}
83
84impl Mul<isize> for Point {
85 type Output = Point;
86
87 fn mul(self, other: isize) -> Point {
88 Point::new(self.x * other, self.y * other)
89 }
90}
91
92impl<A> Index<Point> for Vec<Vec<A>> {
93 type Output = A;
94
95 fn index(&self, index: Point) -> &A {
96 let x: usize = index.x.try_into().unwrap();
97 let y: usize = index.y.try_into().unwrap();
98 &self[y][x]
99 }
100}
101
102impl<A, const SIZE_OUTER: usize, const SIZE_INNER: usize> Index<Point> for [[A; SIZE_INNER]; SIZE_OUTER] {
103 type Output = A;
104
105 fn index(&self, index: Point) -> &A {
106 let x: usize = index.x.try_into().unwrap();
107 let y: usize = index.y.try_into().unwrap();
108 &self[y][x]
109 }
110}
111
112impl <A> IndexMut<Point> for Vec<Vec<A>> {
113 fn index_mut(&mut self, index: Point) -> &mut A {
114 let x: usize = index.x.try_into().unwrap();
115 let y: usize = index.y.try_into().unwrap();
116 &mut self[y][x]
117 }
118}
119
120impl <A, const SIZE_OUTER: usize, const SIZE_INNER: usize> IndexMut<Point> for [[A; SIZE_INNER]; SIZE_OUTER] {
121 fn index_mut(&mut self, index: Point) -> &mut A {
122 let x: usize = index.x.try_into().unwrap();
123 let y: usize = index.y.try_into().unwrap();
124 &mut self[y][x]
125 }
126}
127
128
129pub trait Get{
132 type Output;
133 fn get_option(&self, point: Point) -> Option<&Self::Output>;
134 fn get_mut_option(&mut self, point: Point) -> Option<&mut Self::Output>;
135}
136
137impl<A> Get for Vec<Vec<A>> {
138 type Output = A;
139
140 fn get_option(&self, point: Point) -> Option<&Self::Output> {
141 let x: usize = point.x.try_into().ok()?;
142 let y: usize = point.y.try_into().ok()?;
143 self.get(y)?.get(x)
144 }
145
146 fn get_mut_option(&mut self, point: Point) -> Option<&mut Self::Output> {
147 let x: usize = point.x.try_into().ok()?;
148 let y: usize = point.y.try_into().ok()?;
149 self.get_mut(y)?.get_mut(x)
150 }
151}
152
153impl<A, const SIZE_INNER: usize, const SIZE_OUTER: usize> Get for [[A; SIZE_INNER]; SIZE_OUTER] {
154 type Output = A;
155
156 fn get_option(&self, point: Point) -> Option<&Self::Output> {
157 let x: usize = point.x.try_into().ok()?;
158 let y: usize = point.y.try_into().ok()?;
159 self.get(y)?.get(x)
160 }
161
162 fn get_mut_option(&mut self, point: Point) -> Option<&mut Self::Output> {
163 let x: usize = point.x.try_into().ok()?;
164 let y: usize = point.y.try_into().ok()?;
165 self.get_mut(y)?.get_mut(x)
166 }
167}
168
169
170pub trait Set{
174 type Output;
175 fn set(&mut self, point: Point, value: Self::Output) -> Option<Self::Output>;
176}
177
178impl<A> Set for Vec<Vec<A>> {
179 type Output = A;
180
181 fn set(&mut self, point: Point, value: Self::Output) -> Option<Self::Output> {
182 let x: usize = point.x.try_into().ok()?;
183 let y: usize = point.y.try_into().ok()?;
184 let inner = self.get_mut(y)?;
185 let location = inner.get_mut(x)?;
186 Some(mem::replace(location, value))
187 }
188}
189
190impl<A, const SIZE_INNER: usize, const SIZE_OUTER: usize> Set for [[A; SIZE_INNER]; SIZE_OUTER] {
191 type Output = A;
192
193 fn set(&mut self, point: Point, value: Self::Output) -> Option<Self::Output> {
194 let x: usize = point.x.try_into().ok()?;
195 let y: usize = point.y.try_into().ok()?;
196 Some(mem::replace(self.get_mut(y)?.get_mut(x)?, value))
197 }
198}
199
200
201
202
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207
208 #[test]
209 fn it_works() {
210 let v = vec![vec![0; 3]; 3];
211
212 assert_eq!(v[Point::new(1, 1)], 0);
213 }
214 #[test]
215 fn it_works_array() {
216 let v = [[0; 3]; 3];
217
218 assert_eq!(v[Point::new(1, 1)], 0);
219 }
220 #[test]
221 fn basic_mutation() {
222 let mut v = vec![vec![0; 3]; 3];
223 let point = Point::new(1, 1);
224 v[point] = 1;
225
226 assert_eq!(v[point], 1);
227 }
228 #[test]
229 fn basic_mutation_array() {
230 let mut v = [[0; 3]; 3];
231 let point = Point::new(1, 1);
232 v[point] = 1;
233
234 assert_eq!(v[point], 1);
235 }
236 #[test]
237 fn basic_point_addition() {
238 let v = [[1, 1, 1, 2]; 3];
239 let point = Point::new(1, 1) + Point::new(2, 0);
240 assert_eq!(v[point], 2);
241 }
242 #[test]
243 fn basic_multiplication() {
244 let v = [[1, 1, 1, 2]; 3];
245 let point = Point::new(1, 1) + RIGHT * 2;
246 assert_eq!(v[point], 2);
247 }
248}