geo_traits/
point.rs

1use std::marker::PhantomData;
2
3#[cfg(feature = "geo-types")]
4use geo_types::{Coord, CoordNum, Point};
5
6use crate::{CoordTrait, GeometryTrait, UnimplementedCoord};
7
8/// A trait for accessing data from a generic Point.
9///
10/// Refer to [geo_types::Point] for information about semantics and validity.
11pub trait PointTrait: Sized + GeometryTrait {
12    /// The coordinate type of this geometry
13    /// The type of the underlying coordinate, which implements [CoordTrait]
14    type CoordType<'a>: 'a + CoordTrait<T = <Self as GeometryTrait>::T>
15    where
16        Self: 'a;
17
18    /// The location of this 0-dimensional geometry.
19    ///
20    /// According to Simple Features, a Point can have zero coordinates and be considered "empty".
21    fn coord(&self) -> Option<Self::CoordType<'_>>;
22}
23
24#[cfg(feature = "geo-types")]
25impl<T: CoordNum> PointTrait for Point<T> {
26    type CoordType<'a>
27        = Coord<<Self as GeometryTrait>::T>
28    where
29        Self: 'a;
30
31    fn coord(&self) -> Option<Self::CoordType<'_>> {
32        Some(self.0)
33    }
34}
35
36#[cfg(feature = "geo-types")]
37impl<T: CoordNum> PointTrait for &'_ Point<T> {
38    type CoordType<'a>
39        = Coord<<Self as GeometryTrait>::T>
40    where
41        Self: 'a;
42
43    fn coord(&self) -> Option<Self::CoordType<'_>> {
44        Some(self.0)
45    }
46}
47
48/// An empty struct that implements [PointTrait].
49///
50/// This can be used as the `PointType` of the `GeometryTrait` by implementations that don't have a
51/// Point concept
52pub struct UnimplementedPoint<T>(PhantomData<T>);
53
54impl<T> PointTrait for UnimplementedPoint<T> {
55    type CoordType<'a>
56        = UnimplementedCoord<<Self as GeometryTrait>::T>
57    where
58        Self: 'a;
59
60    fn coord(&self) -> Option<Self::CoordType<'_>> {
61        unimplemented!()
62    }
63}