75 /// Consumes partially the iterator to tell if the given target |
75 /// Consumes partially the iterator to tell if the given target |
76 /// revision |
76 /// revision |
77 /// is in the ancestors it emits. |
77 /// is in the ancestors it emits. |
78 /// This is meant for iterators actually dedicated to that kind of |
78 /// This is meant for iterators actually dedicated to that kind of |
79 /// purpose |
79 /// purpose |
80 pub fn contains(&mut self, target: Revision) -> bool { |
80 pub fn contains(&mut self, target: Revision) -> Result<bool, GraphError> { |
81 if self.seen.contains(&target) && target != NULL_REVISION { |
81 if self.seen.contains(&target) && target != NULL_REVISION { |
82 return true; |
82 return Ok(true); |
83 } |
83 } |
84 for rev in self { |
84 for item in self { |
|
85 let rev = item?; |
85 if rev == target { |
86 if rev == target { |
86 return true; |
87 return Ok(true); |
87 } |
88 } |
88 if rev < target { |
89 if rev < target { |
89 return false; |
90 return Ok(false); |
90 } |
91 } |
91 } |
92 } |
92 false |
93 Ok(false) |
93 } |
94 } |
94 } |
95 } |
95 |
96 |
96 /// Main implementation. |
97 /// Main implementation. |
97 /// |
98 /// |
115 /// - this is probably what the Python implementation produces anyway, due |
116 /// - this is probably what the Python implementation produces anyway, due |
116 /// to filtering at each step, and Python code is currently the only |
117 /// to filtering at each step, and Python code is currently the only |
117 /// concrete caller we target, so we shouldn't need a finer error treatment |
118 /// concrete caller we target, so we shouldn't need a finer error treatment |
118 /// for the time being. |
119 /// for the time being. |
119 impl<G: Graph> Iterator for AncestorsIterator<G> { |
120 impl<G: Graph> Iterator for AncestorsIterator<G> { |
120 type Item = Revision; |
121 type Item = Result<Revision, GraphError>; |
121 |
122 |
122 fn next(&mut self) -> Option<Revision> { |
123 fn next(&mut self) -> Option<Self::Item> { |
123 let current = match self.visit.peek() { |
124 let current = match self.visit.peek() { |
124 None => { |
125 None => { |
125 return None; |
126 return None; |
126 } |
127 } |
127 Some(c) => *c, |
128 Some(c) => *c, |
128 }; |
129 }; |
129 let (p1, p2) = self |
130 let (p1, p2) = match self.graph.parents(current) { |
130 .graph |
131 Ok(ps) => ps, |
131 .parents(current) |
132 Err(e) => return Some(Err(e)), |
132 .unwrap_or((NULL_REVISION, NULL_REVISION)); |
133 }; |
133 if p1 < self.stoprev || self.seen.contains(&p1) { |
134 if p1 < self.stoprev || self.seen.contains(&p1) { |
134 self.visit.pop(); |
135 self.visit.pop(); |
135 } else { |
136 } else { |
136 *(self.visit.peek_mut().unwrap()) = p1; |
137 *(self.visit.peek_mut().unwrap()) = p1; |
137 self.seen.insert(p1); |
138 self.seen.insert(p1); |
138 }; |
139 }; |
139 |
140 |
140 self.conditionally_push_rev(p2); |
141 self.conditionally_push_rev(p2); |
141 Some(current) |
142 Some(Ok(current)) |
142 } |
143 } |
143 } |
144 } |
144 |
145 |
145 #[cfg(test)] |
146 #[cfg(test)] |
146 mod tests { |
147 mod tests { |