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}