map_tile_toolkit/
polygon_view.rs1use core::ops::Range;
6
7use crate::TileError;
8use crate::vertex::PolyVertex;
9
10pub(crate) fn offset(len: usize) -> Result<u32, TileError> {
13 u32::try_from(len).map_err(|_| TileError::GeometryTooLarge)
14}
15
16pub(crate) fn span(ends: &[u32], i: usize) -> Range<usize> {
18 let start = if i == 0 { 0 } else { ends[i - 1] as usize };
19 start..ends[i] as usize
20}
21
22pub struct PolygonView<'a, V: PolyVertex, A = ()> {
25 verts: &'a [V],
26 ring_ends: &'a [u32],
27 first: usize,
29 end: usize,
30 attr: &'a A,
31}
32
33impl<'a, V: PolyVertex, A> PolygonView<'a, V, A> {
34 pub(crate) fn new(
35 verts: &'a [V],
36 ring_ends: &'a [u32],
37 rings: Range<usize>,
38 attr: &'a A,
39 ) -> Self {
40 Self {
41 verts,
42 ring_ends,
43 first: rings.start,
44 end: rings.end,
45 attr,
46 }
47 }
48
49 #[must_use]
51 pub fn attr(&self) -> &'a A {
52 self.attr
53 }
54
55 pub fn iter_rings(&self) -> impl Iterator<Item = RingView<'a, V>> + use<'a, V, A> {
58 let (verts, ends, first) = (self.verts, self.ring_ends, self.first);
59 (first..self.end).map(move |r| RingView {
60 verts: &verts[span(ends, r)],
61 is_hole: r != first,
62 })
63 }
64}
65
66pub struct RingView<'a, V: PolyVertex> {
68 verts: &'a [V],
69 is_hole: bool,
70}
71
72impl<'a, V: PolyVertex> RingView<'a, V> {
73 #[must_use]
75 pub fn vertices(&self) -> &'a [V] {
76 self.verts
77 }
78
79 #[must_use]
81 pub fn is_hole(&self) -> bool {
82 self.is_hole
83 }
84}
85
86macro_rules! copy_view {
88 ($($view:ident<$($param:ident),*>: $bound:path),* $(,)?) => {$(
89 #[allow(
90 clippy::expl_impl_clone_on_copy,
91 reason = "a derive would require the vertex and attribute types to be Copy too; some views trip the lint and some do not"
92 )]
93 impl<V: $bound, $($param),*> Clone for $view<'_, V, $($param),*> {
94 fn clone(&self) -> Self {
95 *self
96 }
97 }
98 impl<V: $bound, $($param),*> Copy for $view<'_, V, $($param),*> {}
99 )*};
100}
101pub(crate) use copy_view;
102
103copy_view!(PolygonView<A>: PolyVertex, RingView<>: PolyVertex);