use std::ops::{Index, IndexMut}; use super::circular_index; /// Game of Life universe building blocks (a plane is a circular Vec) /// /// This is used internally in the implementation of the Universe to allow /// more readable and safer traversing of the universe blocks #[derive(Debug, Clone, PartialEq)] pub(crate) struct Plane(pub Vec); impl Index for Plane { type Output = bool; fn index(&self, idx: isize) -> &bool { let len = self.0.len() as isize; &self.0[circular_index(idx, len)] } } impl IndexMut for Plane { fn index_mut(&mut self, idx: isize) -> &mut Self::Output { let len = self.0.len() as isize; &mut self.0[circular_index(idx, len)] } } #[cfg(test)] mod plane { use super::*; mod index { use super::*; #[test] fn get_element() { let p = Plane(vec![false, false, true, false, false]); assert_eq!(p[0], false); assert_eq!(p[1], false); assert_eq!(p[3], false); assert_eq!(p[4], false); assert_eq!(p[-3], true); assert_eq!(p[2], true); assert_eq!(p[7], true); } } #[cfg(test)] mod index_mut { use super::*; #[test] fn set_negative_index_element() { let mut p = Plane(vec![false, false, false, false, false]); p[-3] = true; assert_eq!(p, Plane(vec![false, false, true, false, false])); } #[test] fn set_element() { let mut p = Plane(vec![false, false, false, false, false]); p[2] = true; assert_eq!(p, Plane(vec![false, false, true, false, false])); } #[test] fn set_out_of_bound_element() { let mut p = Plane(vec![false, false, false, false, false]); p[7] = true; assert_eq!(p, Plane(vec![false, false, true, false, false])); } } }