src/cube.rs

changeset 34
aa6129697116
parent 30
4fc8c93ed7e8
child 37
d7cd14b8ccc0
equal deleted inserted replaced
33:556afeaa34bf 34:aa6129697116
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 struct PathIter { 29 pub enum PathIter {
30 destination : Face, 30 Same {
31 intermediate : AdjacentFaces, 31 destination : Face,
32 current : usize 32 exhausted : bool
33 },
34 Indirect {
35 destination : Face,
36 intermediate : AdjacentFaces,
37 current : usize
38 }
33 } 39 }
34 40
35 impl std::iter::Iterator for PathIter { 41 impl std::iter::Iterator for PathIter {
36 type Item = Path; 42 type Item = Path;
37 43
38 fn next(&mut self) -> Option<Self::Item> { 44 fn next(&mut self) -> Option<Self::Item> {
39 let PathIter { destination, intermediate : ref i, ref mut current } = *self; 45 match *self {
40 while *current < i.len() { 46 PathIter::Same { destination, ref mut exhausted } => {
41 let intermediate = i[*current]; 47 if !*exhausted {
42 *current += 1; 48 *exhausted = true;
43 if intermediate == destination { 49 return Some(Path::Direct { destination })
44 return Some(Path::Direct { destination }) 50 }
45 } else if intermediate != destination.opposing_face() { 51 None
46 return Some(Path::Indirect{ destination, intermediate }) 52 },
47 } 53 PathIter::Indirect { destination, intermediate : ref i, ref mut current } => {
48 // Paths should never go through a face opposing the destination. 54 while *current < i.len() {
49 } 55 let intermediate = i[*current];
50 None 56 *current += 1;
57 if intermediate == destination {
58 return Some(Path::Direct { destination })
59 } else if intermediate != destination.opposing_face() {
60 return Some(Path::Indirect{ destination, intermediate })
61 }
62 // Paths should never go through a face opposing the destination.
63 }
64 None
65 }
66 }
51 } 67 }
52 } 68 }
53 69
54 impl std::fmt::Display for Face { 70 impl std::fmt::Display for Face {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 } 180 }
165 181
166 182
167 /// Returns an iterator over all the paths from `self` to `other`. 183 /// Returns an iterator over all the paths from `self` to `other`.
168 fn paths(&self, other : Face) -> PathIter { 184 fn paths(&self, other : Face) -> PathIter {
169 PathIter { 185 if other == *self {
170 intermediate : self.adjacent_faces(), 186 PathIter::Same {
171 destination : other, 187 destination : other,
172 current : 0 188 exhausted : false
189 }
190 } else {
191 PathIter::Indirect {
192 intermediate : self.adjacent_faces(),
193 destination : other,
194 current : 0
195 }
173 } 196 }
174 } 197 }
175 198
176 /// Indicates whether an unfolded point `p` is on this face, i.e., 199 /// Indicates whether an unfolded point `p` is on this face, i.e.,
177 /// has coordinates in [0,1]². 200 /// has coordinates in [0,1]².

mercurial