Skip to main content

geometry_trait/
geometry.rs

1//! The [`Geometry`] super-trait: every concept refines it.
2//!
3//! Mirrors the role of the two C++ trait metafunctions
4//! `boost::geometry::traits::tag<G>::type`
5//! (`boost/geometry/core/tag.hpp`) and
6//! `boost::geometry::traits::point_type<G>::type`
7//! (`boost/geometry/core/point_type.hpp`): every modelled geometry
8//! exposes (a) its kind, as one of the `*Tag` types from
9//! [`geometry_tag`], and (b) the point type its coordinates live in.
10//!
11//! Splitting these two pieces out into a single Rust super-trait
12//! lets every other concept (Point, Segment, Box, Linestring, Ring,
13//! Polygon, …) refine `Geometry<Kind = …>` and inherit the
14//! `type Point` projection without re-stating it.
15
16use crate::point::Point;
17
18/// Every modelled geometry has a *kind* (its tag) and a *point type*
19/// it is built from.
20///
21/// `Kind` matches `boost::geometry::traits::tag<G>::type`
22/// (`boost/geometry/core/tag.hpp`); `Point` matches
23/// `boost::geometry::traits::point_type<G>::type`
24/// (`boost/geometry/core/point_type.hpp`). For a value whose own
25/// kind is [`geometry_tag::PointTag`], the `Point` projection is
26/// `Self`.
27///
28/// # Examples
29///
30/// Dispatch on the geometry kind via the `Kind` associated type:
31///
32/// ```
33/// use geometry_tag::PointTag;
34/// use geometry_trait::Geometry;
35///
36/// fn is_point<G: Geometry<Kind = PointTag>>(_g: &G) {}
37/// ```
38pub trait Geometry {
39    /// One of the `*Tag` types from
40    /// [`geometry_tag`](../geometry_tag/index.html).
41    ///
42    /// Mirrors `boost::geometry::traits::tag<G>::type`
43    /// (`boost/geometry/core/tag.hpp`).
44    type Kind;
45
46    /// The point type this geometry is built from. For a value
47    /// modelling [`Point`], this is `Self`.
48    ///
49    /// Mirrors `boost::geometry::traits::point_type<G>::type`
50    /// (`boost/geometry/core/point_type.hpp`).
51    type Point: Point;
52}