gol_core/cell/
index.rs

1use serde::{Deserialize, Serialize};
2use std::hash::{Hash, Hasher};
3
4pub trait ToGridPointND<T>
5where
6    T: Clone,
7{
8    fn to_nd(&self) -> GridPointND<T>;
9}
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
12pub struct GridPoint1D<T> {
13    pub x: T,
14}
15
16#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct GridPoint2D<T> {
18    pub x: T,
19    pub y: T,
20}
21
22#[derive(Clone, Debug, Serialize, Deserialize)]
23pub struct GridPoint3D<T> {
24    pub x: T,
25    pub y: T,
26    pub z: T,
27}
28
29#[derive(Clone, Debug)]
30pub struct GridPointND<T> {
31    indices: Vec<T>,
32}
33
34impl<T> ToGridPointND<T> for GridPoint1D<T>
35where
36    T: Clone,
37{
38    fn to_nd(&self) -> GridPointND<T> {
39        GridPointND::new(vec![self.x.clone()].iter())
40    }
41}
42
43impl<T> ToGridPointND<T> for GridPoint2D<T>
44where
45    T: Clone,
46{
47    fn to_nd(&self) -> GridPointND<T> {
48        GridPointND::new(vec![self.x.clone(), self.y.clone()].iter())
49    }
50}
51
52impl<T> ToGridPointND<T> for GridPoint3D<T>
53where
54    T: Clone,
55{
56    fn to_nd(&self) -> GridPointND<T> {
57        GridPointND::new(vec![self.x.clone(), self.y.clone(), self.z.clone()].iter())
58    }
59}
60
61impl<T> GridPointND<T> {
62    pub fn new<'a, 'b, I>(indices: I) -> Self
63    where
64        'a: 'b,
65        T: 'a + Clone,
66        I: Iterator<Item = &'b T>,
67    {
68        Self {
69            indices: indices.map(|ele| ele.clone()).collect(),
70        }
71    }
72
73    pub fn indices<'a>(&'a self) -> std::slice::Iter<'a, T> {
74        self.indices.iter()
75    }
76
77    pub fn to_1d(&self) -> Option<GridPoint1D<T>>
78    where
79        T: Clone,
80    {
81        let mut iter = self.indices();
82        let x = iter.next();
83        if x.is_none() {
84            return None;
85        }
86        match iter.next() {
87            Some(_) => None,
88            None => Some(GridPoint1D {
89                x: x.unwrap().clone(),
90            }),
91        }
92    }
93
94    pub fn to_2d(&self) -> Option<GridPoint2D<T>>
95    where
96        T: Clone,
97    {
98        let mut iter = self.indices();
99        let x = iter.next();
100        if x.is_none() {
101            return None;
102        }
103        let y = iter.next();
104        if y.is_none() {
105            return None;
106        }
107        match iter.next() {
108            Some(_) => None,
109            None => Some(GridPoint2D {
110                x: x.unwrap().clone(),
111                y: y.unwrap().clone(),
112            }),
113        }
114    }
115
116    pub fn to_3d(&self) -> Option<GridPoint3D<T>>
117    where
118        T: Clone,
119    {
120        let mut iter = self.indices();
121        let x = iter.next();
122        if x.is_none() {
123            return None;
124        }
125        let y = iter.next();
126        if y.is_none() {
127            return None;
128        }
129        let z = iter.next();
130        if z.is_none() {
131            return None;
132        }
133        match iter.next() {
134            Some(_) => None,
135            None => Some(GridPoint3D {
136                x: x.unwrap().clone(),
137                y: y.unwrap().clone(),
138                z: z.unwrap().clone(),
139            }),
140        }
141    }
142}
143
144impl<T> PartialEq for GridPoint1D<T>
145where
146    T: PartialEq,
147{
148    fn eq(&self, other: &Self) -> bool {
149        self.x == other.x
150    }
151}
152
153impl<T> PartialEq for GridPoint2D<T>
154where
155    T: PartialEq,
156{
157    fn eq(&self, other: &Self) -> bool {
158        self.x == other.x && self.y == other.y
159    }
160}
161
162impl<T> PartialEq for GridPoint3D<T>
163where
164    T: PartialEq,
165{
166    fn eq(&self, other: &Self) -> bool {
167        self.x == other.x && self.y == other.y && self.z == other.z
168    }
169}
170
171impl<T> PartialEq for GridPointND<T>
172where
173    T: PartialEq,
174{
175    fn eq(&self, other: &Self) -> bool {
176        let mut not_eq_res = self.indices().zip(other.indices()).filter(|(a, b)| a != b);
177        match not_eq_res.next() {
178            Some(_) => false,
179            None => true,
180        }
181    }
182}
183
184impl<T> Eq for GridPoint1D<T> where T: PartialEq {}
185impl<T> Eq for GridPoint2D<T> where T: PartialEq {}
186impl<T> Eq for GridPoint3D<T> where T: PartialEq {}
187impl<T> Eq for GridPointND<T> where T: PartialEq {}
188
189impl<T> Hash for GridPoint1D<T>
190where
191    T: Hash,
192{
193    fn hash<H: Hasher>(&self, state: &mut H) {
194        self.x.hash(state);
195    }
196}
197
198impl<T> Hash for GridPoint2D<T>
199where
200    T: Hash,
201{
202    fn hash<H: Hasher>(&self, state: &mut H) {
203        self.x.hash(state);
204        self.y.hash(state);
205    }
206}
207
208impl<T> Hash for GridPoint3D<T>
209where
210    T: Hash,
211{
212    fn hash<H: Hasher>(&self, state: &mut H) {
213        self.x.hash(state);
214        self.y.hash(state);
215        self.z.hash(state);
216    }
217}
218
219impl<T> Hash for GridPointND<T>
220where
221    T: Hash,
222{
223    fn hash<H: Hasher>(&self, state: &mut H) {
224        for idx in self.indices() {
225            idx.hash(state)
226        }
227    }
228}
229
230impl<T> GridPoint3D<T> {
231    pub fn new(x: T, y: T, z: T) -> Self {
232        Self { x, y, z }
233    }
234}
235
236impl<T> GridPoint2D<T> {
237    pub fn new(x: T, y: T) -> Self {
238        Self { x, y }
239    }
240}
241
242impl<T> GridPoint1D<T> {
243    pub fn new(x: T) -> Self {
244        Self { x }
245    }
246}