24 Indirect { destination : Face, intermediate : Face }, |
24 Indirect { destination : Face, intermediate : Face }, |
25 } |
25 } |
26 |
26 |
27 /// An iterator over paths on a cube, from a source face to a destination face. |
27 /// An iterator over paths on a cube, from a source face to a destination face. |
28 #[derive(Clone, Debug)] |
28 #[derive(Clone, Debug)] |
29 pub enum PathIter { |
29 pub struct PathIter { |
30 Direct(Face), |
30 destination : Face, |
31 Indirect{ destination : Face, intermediate : AdjacentFaces, current : usize}, |
31 intermediate : AdjacentFaces, |
32 Exhausted, |
32 current : usize |
33 } |
33 } |
34 |
34 |
35 impl std::iter::Iterator for PathIter { |
35 impl std::iter::Iterator for PathIter { |
36 type Item = Path; |
36 type Item = Path; |
37 |
37 |
38 fn next(&mut self) -> Option<Self::Item> { |
38 fn next(&mut self) -> Option<Self::Item> { |
39 use PathIter::*; |
39 let PathIter { destination, intermediate : ref i, ref mut current } = *self; |
40 match self { |
40 while *current < i.len() { |
41 &mut Exhausted => None, |
41 let intermediate = i[*current]; |
42 &mut Direct(destination) => { |
42 *current += 1; |
43 *self = Exhausted; |
43 if intermediate == destination { |
44 Some(Path::Direct { destination }) |
44 return Some(Path::Direct { destination }) |
45 }, |
45 } else if intermediate != destination.opposing_face() { |
46 &mut Indirect{destination, intermediate : ref i, ref mut current} => { |
46 return Some(Path::Indirect{ destination, intermediate }) |
47 if *current < i.len() { |
47 } |
48 let intermediate = i[*current]; |
48 // Paths should never go through a face opposing the destination. |
49 *current += 1; |
49 } |
50 Some(Path::Indirect{ destination, intermediate }) |
50 None |
51 } else { |
|
52 *self = Exhausted; |
|
53 None |
|
54 } |
|
55 } |
|
56 } |
|
57 } |
51 } |
58 } |
52 } |
59 |
53 |
60 impl std::fmt::Display for Face { |
54 impl std::fmt::Display for Face { |
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
170 } |
164 } |
171 |
165 |
172 |
166 |
173 /// Returns an iterator over all the paths from `self` to `other`. |
167 /// Returns an iterator over all the paths from `self` to `other`. |
174 fn paths(&self, other : Face) -> PathIter { |
168 fn paths(&self, other : Face) -> PathIter { |
175 //dbg!(self, other); |
169 PathIter { |
176 if self.opposing_face() == other { |
170 intermediate : self.adjacent_faces(), |
177 PathIter::Indirect { |
171 destination : other, |
178 intermediate : self.adjacent_faces(), |
172 current : 0 |
179 destination : other, |
|
180 current : 0 |
|
181 } |
|
182 } else { |
|
183 PathIter::Direct(other) |
|
184 } |
173 } |
185 } |
174 } |
186 |
175 |
187 /// Indicates whether an unfolded point `p` is on this face, i.e., |
176 /// Indicates whether an unfolded point `p` is on this face, i.e., |
188 /// has coordinates in [0,1]². |
177 /// has coordinates in [0,1]². |