geo_traits/
triangle.rs

1use std::marker::PhantomData;
2
3use crate::{CoordTrait, GeometryTrait, UnimplementedCoord};
4#[cfg(feature = "geo-types")]
5use geo_types::{Coord, CoordNum, Triangle};
6
7/// A trait for accessing data from a generic Triangle.
8///
9/// A triangle is a bounded area whose three vertices are defined by [coordinates][CoordTrait].
10///
11/// Refer to [geo_types::Triangle] for information about semantics and validity.
12pub trait TriangleTrait: Sized + GeometryTrait {
13    /// The type of each underlying coordinate, which implements [CoordTrait]
14    type CoordType<'a>: 'a + CoordTrait<T = Self::T>
15    where
16        Self: 'a;
17
18    /// Access the first coordinate in this Triangle
19    fn first(&self) -> Self::CoordType<'_>;
20
21    /// Access the second coordinate in this Triangle
22    fn second(&self) -> Self::CoordType<'_>;
23
24    /// Access the third coordinate in this Triangle
25    fn third(&self) -> Self::CoordType<'_>;
26
27    /// Access the three underlying coordinates
28    fn coords(&self) -> [Self::CoordType<'_>; 3] {
29        [self.first(), self.second(), self.third()]
30    }
31}
32
33#[cfg(feature = "geo-types")]
34impl<T: CoordNum> TriangleTrait for Triangle<T> {
35    type CoordType<'a>
36        = &'a Coord<Self::T>
37    where
38        Self: 'a;
39
40    fn first(&self) -> Self::CoordType<'_> {
41        &self.0
42    }
43
44    fn second(&self) -> Self::CoordType<'_> {
45        &self.1
46    }
47
48    fn third(&self) -> Self::CoordType<'_> {
49        &self.2
50    }
51}
52
53#[cfg(feature = "geo-types")]
54impl<'a, T: CoordNum> TriangleTrait for &'a Triangle<T> {
55    type CoordType<'b>
56        = &'a Coord<Self::T>
57    where
58        Self: 'b;
59
60    fn first(&self) -> Self::CoordType<'_> {
61        &self.0
62    }
63
64    fn second(&self) -> Self::CoordType<'_> {
65        &self.0
66    }
67
68    fn third(&self) -> Self::CoordType<'_> {
69        &self.0
70    }
71}
72
73/// An empty struct that implements [TriangleTrait].
74///
75/// This can be used as the `TriangleType` of the `GeometryTrait` by implementations that don't
76/// have a Triangle concept
77pub struct UnimplementedTriangle<T>(PhantomData<T>);
78
79impl<T> TriangleTrait for UnimplementedTriangle<T> {
80    type CoordType<'a>
81        = UnimplementedCoord<Self::T>
82    where
83        Self: 'a;
84
85    fn first(&self) -> Self::CoordType<'_> {
86        unimplemented!()
87    }
88
89    fn second(&self) -> Self::CoordType<'_> {
90        unimplemented!()
91    }
92
93    fn third(&self) -> Self::CoordType<'_> {
94        unimplemented!()
95    }
96}