geo_traits/
multi_polygon.rs1use std::marker::PhantomData;
2
3use crate::iterator::MultiPolygonIterator;
4use crate::polygon::UnimplementedPolygon;
5use crate::{GeometryTrait, PolygonTrait};
6#[cfg(feature = "geo-types")]
7use geo_types::{CoordNum, MultiPolygon, Polygon};
8
9pub trait MultiPolygonTrait: Sized + GeometryTrait {
13 type InnerPolygonType<'a>: 'a + PolygonTrait<T = Self::T>
15 where
16 Self: 'a;
17
18 fn polygons(
20 &self,
21 ) -> impl DoubleEndedIterator + ExactSizeIterator<Item = Self::InnerPolygonType<'_>> {
22 MultiPolygonIterator::new(self, 0, self.num_polygons())
23 }
24
25 fn num_polygons(&self) -> usize;
27
28 fn polygon(&self, i: usize) -> Option<Self::InnerPolygonType<'_>> {
31 if i >= self.num_polygons() {
32 None
33 } else {
34 unsafe { Some(self.polygon_unchecked(i)) }
35 }
36 }
37
38 unsafe fn polygon_unchecked(&self, i: usize) -> Self::InnerPolygonType<'_>;
44}
45
46#[cfg(feature = "geo-types")]
47impl<T: CoordNum> MultiPolygonTrait for MultiPolygon<T> {
48 type InnerPolygonType<'a>
49 = &'a Polygon<Self::T>
50 where
51 Self: 'a;
52
53 fn num_polygons(&self) -> usize {
54 self.0.len()
55 }
56
57 unsafe fn polygon_unchecked(&self, i: usize) -> Self::InnerPolygonType<'_> {
58 self.0.get_unchecked(i)
59 }
60}
61
62#[cfg(feature = "geo-types")]
63impl<'a, T: CoordNum> MultiPolygonTrait for &'a MultiPolygon<T> {
64 type InnerPolygonType<'b>
65 = &'a Polygon<Self::T>
66 where
67 Self: 'b;
68
69 fn num_polygons(&self) -> usize {
70 self.0.len()
71 }
72
73 unsafe fn polygon_unchecked(&self, i: usize) -> Self::InnerPolygonType<'_> {
74 self.0.get_unchecked(i)
75 }
76}
77
78pub struct UnimplementedMultiPolygon<T>(PhantomData<T>);
83
84impl<T> MultiPolygonTrait for UnimplementedMultiPolygon<T> {
85 type InnerPolygonType<'a>
86 = UnimplementedPolygon<Self::T>
87 where
88 Self: 'a;
89
90 fn num_polygons(&self) -> usize {
91 unimplemented!()
92 }
93
94 unsafe fn polygon_unchecked(&self, _i: usize) -> Self::InnerPolygonType<'_> {
95 unimplemented!()
96 }
97}