embedded_graphics/primitives/polyline/
points.rs1use crate::{
2 geometry::Point,
3 primitives::{
4 line::{self, Line},
5 polyline::Polyline,
6 PointsIter,
7 },
8};
9
10#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
12#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
13pub struct Points<'a> {
14 vertices: &'a [Point],
15 translate: Point,
16 segment_iter: line::Points,
17}
18
19impl<'a> Points<'a> {
20 pub(in crate::primitives) fn new<'b>(polyline: &'b Polyline<'a>) -> Self
21 where
22 'a: 'b,
23 {
24 polyline
25 .vertices
26 .split_first()
27 .and_then(|(start, rest)| {
28 rest.get(0).map(|end| Points {
30 vertices: rest,
31 translate: polyline.translate,
32 segment_iter: Line::new(*start + polyline.translate, *end + polyline.translate)
33 .points(),
34 })
35 })
36 .unwrap_or_else(||
37 Points {
40 vertices: &[],
41 translate: Point::zero(),
42 segment_iter: line::Points::empty(),
43 })
44 }
45}
46
47impl<'a> Iterator for Points<'a> {
48 type Item = Point;
49
50 fn next(&mut self) -> Option<Self::Item> {
51 if let Some(p) = self.segment_iter.next() {
52 Some(p)
53 } else {
54 let (start, rest) = self.vertices.split_first()?;
55 let end = rest.get(0)?;
56
57 self.vertices = rest;
58
59 self.segment_iter = Line::new(*start + self.translate, *end + self.translate).points();
60
61 self.nth(1)
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::primitives::polyline::tests::SMALL;
71
72 #[test]
74 fn no_duplicate_points() {
75 let expected: [Point; 14] = [
76 Point::new(2, 5),
77 Point::new(3, 4),
78 Point::new(4, 3),
79 Point::new(5, 2),
80 Point::new(6, 3),
81 Point::new(7, 3),
82 Point::new(8, 4),
83 Point::new(9, 4),
84 Point::new(10, 5),
85 Point::new(11, 4),
86 Point::new(12, 4),
87 Point::new(13, 3),
88 Point::new(14, 3),
89 Point::new(15, 2),
90 ];
91
92 assert!(Polyline::new(&SMALL).points().eq(expected.iter().copied()))
93 }
94
95 #[test]
96 fn one_point() {
97 let points = &[Point::zero()];
98
99 let polyline = Polyline::new(points);
100
101 assert!(polyline.points().eq(core::iter::empty()));
102 }
103
104 #[test]
105 fn equal_points() {
106 let points: [Point; 3] = [Point::new(2, 5), Point::new(2, 5), Point::new(2, 5)];
107
108 assert!(Polyline::new(&points)
109 .points()
110 .eq(core::iter::once(Point::new(2, 5))));
111 }
112}