line_drawing/steps.rs
1//! An iterator that returns `(start, end)` tuples from the walk.
2
3/// An iterator that returns `(start, end)` tuples from the walk.
4///
5/// All the algorithms in this crate should have a `steps()` function associated with them to turn
6/// them into a [`Steps`] iterator.
7///
8/// Example using [`WalkGrid`]:
9///
10/// ```
11/// extern crate line_drawing;
12/// use line_drawing::WalkGrid;
13///
14/// fn main() {
15/// for (start, end) in WalkGrid::new((0, 0), (5, 3)).steps() {
16/// println!("{:?} -> {:?}", start, end);
17/// }
18/// }
19/// ```
20///
21/// ```text
22/// (0, 0) -> (1, 0)
23/// (1, 0) -> (1, 1)
24/// (1, 1) -> (2, 1)
25/// (2, 1) -> (2, 2)
26/// (2, 2) -> (3, 2)
27/// (3, 2) -> (4, 2)
28/// (4, 2) -> (4, 3)
29/// (4, 3) -> (5, 3)
30/// ```
31///
32/// [`Steps`]: struct.Steps.html
33/// [`WalkGrid`]: ../struct.WalkGrid.html
34pub struct Steps<T, I> {
35 iterator: I,
36 prev: Option<T>,
37}
38
39impl<T: Copy, I: Iterator<Item = T>> Steps<T, I> {
40 #[inline]
41 pub fn new(mut iterator: I) -> Self {
42 Self {
43 prev: iterator.next(),
44 iterator,
45 }
46 }
47}
48
49impl<T: Copy, I: Iterator<Item = T>> Iterator for Steps<T, I> {
50 type Item = (T, T);
51
52 #[inline]
53 fn next(&mut self) -> Option<Self::Item> {
54 self.iterator.next().and_then(|next| {
55 self.prev.map(|prev| {
56 self.prev = Some(next);
57 (prev, next)
58 })
59 })
60 }
61}
62
63#[test]
64fn steps() {
65 use Midpoint;
66
67 assert_eq!(
68 Midpoint::new((0.0, 0.0), (3.0, 4.0))
69 .steps()
70 .collect::<Vec<_>>(),
71 [
72 ((0, 0), (1, 1)),
73 ((1, 1), (2, 2)),
74 ((2, 2), (2, 3)),
75 ((2, 3), (3, 4))
76 ]
77 );
78}