Skip to main content

geometry_tag/
hierarchy.rs

1//! Marker traits that reproduce the C++ tag inheritance hierarchy.
2//!
3//! In `boost/geometry/core/tags.hpp` the kind tags inherit from category
4//! tags (`point_tag : single_tag, pointlike_tag`, etc.). Rust has no struct
5//! inheritance, so we replace each category with an empty marker trait and
6//! implement the trait for every tag that would inherit from the C++ base.
7//! A bound like `G::Kind: Linear` then automatically covers `SegmentTag`,
8//! `LinestringTag`, and `MultiLinestringTag` — the equivalent of
9//! `tag_cast<Tag, ..., linear_tag>` (`boost/geometry/core/tag_cast.hpp`).
10
11use crate::tag::{
12    BoxTag, GeometryCollectionTag, LinestringTag, MultiLinestringTag, MultiPointTag,
13    MultiPolygonTag, PointTag, PolygonTag, PolyhedralSurfaceTag, RingTag, SegmentTag,
14};
15
16/// Single-geometry marker — counterpart of `single_tag` (`boost/geometry/core/tags.hpp:59`).
17///
18/// # Examples
19///
20/// ```
21/// use geometry_tag::{PointTag, RingTag, Single};
22/// fn k<T: Single>() {}
23/// k::<PointTag>();
24/// k::<RingTag>();
25/// ```
26pub trait Single {}
27
28/// Multi-geometry marker — counterpart of `multi_tag` (`boost/geometry/core/tags.hpp:63`).
29///
30/// # Examples
31///
32/// ```
33/// use geometry_tag::{Multi, MultiPointTag, MultiPolygonTag};
34/// fn k<T: Multi>() {}
35/// k::<MultiPointTag>();
36/// k::<MultiPolygonTag>();
37/// ```
38pub trait Multi {}
39
40/// Point-like category marker — counterpart of `pointlike_tag` (`boost/geometry/core/tags.hpp:66`).
41///
42/// # Examples
43///
44/// ```
45/// use geometry_tag::{MultiPointTag, PointTag, Pointlike};
46/// fn k<T: Pointlike>() {}
47/// k::<PointTag>();
48/// k::<MultiPointTag>();
49/// ```
50pub trait Pointlike {}
51
52/// Linear category marker — counterpart of `linear_tag` (`boost/geometry/core/tags.hpp:69`).
53///
54/// # Examples
55///
56/// ```
57/// use geometry_tag::{Linear, LinestringTag, MultiLinestringTag, SegmentTag};
58/// fn k<T: Linear>() {}
59/// k::<SegmentTag>();
60/// k::<LinestringTag>();
61/// k::<MultiLinestringTag>();
62/// ```
63pub trait Linear {}
64
65/// Polylinear category marker — counterpart of `polylinear_tag : linear_tag`
66/// (`boost/geometry/core/tags.hpp:72`). The C++ inheritance is expressed as
67/// a Rust super-trait bound, so `T: Polylinear` automatically implies
68/// `T: Linear`.
69///
70/// # Examples
71///
72/// ```
73/// use geometry_tag::{LinestringTag, MultiLinestringTag, Polylinear};
74/// fn k<T: Polylinear>() {}
75/// k::<LinestringTag>();
76/// k::<MultiLinestringTag>();
77/// ```
78pub trait Polylinear: Linear {}
79
80/// Areal category marker — counterpart of `areal_tag` (`boost/geometry/core/tags.hpp:75`).
81///
82/// # Examples
83///
84/// ```
85/// use geometry_tag::{Areal, BoxTag, PolygonTag, RingTag};
86/// fn k<T: Areal>() {}
87/// k::<BoxTag>();
88/// k::<RingTag>();
89/// k::<PolygonTag>();
90/// ```
91pub trait Areal {}
92
93/// Polygonal category marker — counterpart of `polygonal_tag : areal_tag`
94/// (`boost/geometry/core/tags.hpp:78`). The C++ inheritance is expressed as
95/// a Rust super-trait bound, so `T: Polygonal` automatically implies
96/// `T: Areal`.
97///
98/// # Examples
99///
100/// ```
101/// use geometry_tag::{MultiPolygonTag, Polygonal, RingTag};
102/// fn k<T: Polygonal>() {}
103/// k::<RingTag>();
104/// k::<MultiPolygonTag>();
105/// ```
106pub trait Polygonal: Areal {}
107
108/// Volumetric category marker — counterpart of `volumetric_tag`
109/// (`boost/geometry/core/tags.hpp:81`).
110///
111/// # Examples
112///
113/// ```
114/// use geometry_tag::{PolyhedralSurfaceTag, Volumetric};
115/// fn k<T: Volumetric>() {}
116/// k::<PolyhedralSurfaceTag>();
117/// ```
118pub trait Volumetric {}
119
120// --- PointTag : single_tag, pointlike_tag ----------------------------------
121impl Single for PointTag {}
122impl Pointlike for PointTag {}
123
124// --- SegmentTag : single_tag, linear_tag -----------------------------------
125impl Single for SegmentTag {}
126impl Linear for SegmentTag {}
127
128// --- LinestringTag : single_tag, polylinear_tag (-> linear_tag) ------------
129impl Single for LinestringTag {}
130impl Linear for LinestringTag {}
131impl Polylinear for LinestringTag {}
132
133// --- RingTag : single_tag, polygonal_tag (-> areal_tag) --------------------
134impl Single for RingTag {}
135impl Areal for RingTag {}
136impl Polygonal for RingTag {}
137
138// --- PolygonTag : single_tag, polygonal_tag (-> areal_tag) -----------------
139impl Single for PolygonTag {}
140impl Areal for PolygonTag {}
141impl Polygonal for PolygonTag {}
142
143// --- BoxTag : single_tag, areal_tag ----------------------------------------
144impl Single for BoxTag {}
145impl Areal for BoxTag {}
146
147// --- MultiPointTag : multi_tag, pointlike_tag ------------------------------
148impl Multi for MultiPointTag {}
149impl Pointlike for MultiPointTag {}
150
151// --- MultiLinestringTag : multi_tag, polylinear_tag (-> linear_tag) --------
152impl Multi for MultiLinestringTag {}
153impl Linear for MultiLinestringTag {}
154impl Polylinear for MultiLinestringTag {}
155
156// --- MultiPolygonTag : multi_tag, polygonal_tag (-> areal_tag) -------------
157impl Multi for MultiPolygonTag {}
158impl Areal for MultiPolygonTag {}
159impl Polygonal for MultiPolygonTag {}
160
161// --- GeometryCollectionTag : multi_tag -------------------------------------
162impl Multi for GeometryCollectionTag {}
163
164// --- PolyhedralSurfaceTag : single_tag, volumetric_tag ---------------------
165impl Single for PolyhedralSurfaceTag {}
166impl Volumetric for PolyhedralSurfaceTag {}