Skip to main content

geometry_trait/
check.rs

1//! Concept-check helpers — call these in unit tests next to your type
2//! to surface adaptation errors close to the source.
3//!
4//! Mirrors `boost::geometry::concepts::check<T>()` from
5//! `boost/geometry/geometries/concepts/check.hpp` and the per-concept
6//! `*_concept.hpp` files. Each helper has an empty body — the trait
7//! bound *is* the check. Wiring it into a unit test next to the type
8//! definition makes the compiler report the adaptation error against
9//! that unit test line, not against the algorithm call site that
10//! happened to be the first thing to instantiate the bound.
11//!
12//! See `boost/geometry/test/concepts/point_well_formed*.cpp` for the
13//! positive Boost counterparts and
14//! `boost/geometry/test/concepts/point_without_*.cpp` for the
15//! compile-fail counterparts that the `tests/ui/*` fixtures mirror.
16//!
17//! # Examples
18//!
19//! ```
20//! use geometry_cs::Cartesian;
21//! use geometry_tag::PointTag;
22//! use geometry_trait::{check_point, Geometry, Point};
23//!
24//! #[derive(Default)]
25//! struct Xy { x: f64, y: f64 }
26//! impl Geometry for Xy { type Kind = PointTag; type Point = Self; }
27//! impl Point for Xy {
28//!     type Scalar = f64; type Cs = Cartesian; const DIM: usize = 2;
29//!     fn get<const D: usize>(&self) -> f64 { if D == 0 { self.x } else { self.y } }
30//! }
31//!
32//! // Compile-time check that `Xy` correctly models the `Point` concept.
33//! check_point::<Xy>();
34//! ```
35
36use crate::{
37    Box, GeometryCollection, IndexedAccess, Linestring, MultiLinestring, MultiPoint, MultiPolygon,
38    Point, Polygon, PolyhedralSurface, Ring, Segment,
39};
40
41/// Call this in a unit test next to your type definition to surface
42/// adaptation errors close to the source rather than at the algorithm
43/// call site.
44///
45/// Mirrors `boost::geometry::concepts::check<Point>()` from
46/// `boost/geometry/geometries/concepts/check.hpp` instantiated with
47/// the point-concept specialisation in
48/// `boost/geometry/geometries/concepts/point_concept.hpp`.
49///
50/// # Examples
51///
52/// ```
53/// use geometry_trait::check_point;
54/// fn _call<P: geometry_trait::Point>() { check_point::<P>(); }
55/// ```
56pub fn check_point<T: Point>() {}
57
58/// Call this in a unit test next to your type definition to surface
59/// adaptation errors close to the source rather than at the algorithm
60/// call site.
61///
62/// Mirrors `boost::geometry::concepts::check<Segment>()` driven by
63/// `boost/geometry/geometries/concepts/segment_concept.hpp`.
64///
65/// # Examples
66///
67/// ```
68/// use geometry_trait::check_segment;
69/// fn _call<S: geometry_trait::Segment>() { check_segment::<S>(); }
70/// ```
71pub fn check_segment<T: Segment>() {}
72
73/// Call this in a unit test next to your type definition to surface
74/// adaptation errors close to the source rather than at the algorithm
75/// call site.
76///
77/// Mirrors `boost::geometry::concepts::check<Box>()` driven by
78/// `boost/geometry/geometries/concepts/box_concept.hpp`.
79///
80/// # Examples
81///
82/// ```
83/// use geometry_trait::check_box;
84/// fn _call<B: geometry_trait::Box>() { check_box::<B>(); }
85/// ```
86pub fn check_box<T: Box>() {}
87
88/// Call this in a unit test next to your type definition to surface
89/// adaptation errors close to the source rather than at the algorithm
90/// call site.
91///
92/// Mirrors `boost::geometry::concepts::check<Linestring>()` driven by
93/// `boost/geometry/geometries/concepts/linestring_concept.hpp`.
94///
95/// # Examples
96///
97/// ```
98/// use geometry_trait::check_linestring;
99/// fn _call<L: geometry_trait::Linestring>() { check_linestring::<L>(); }
100/// ```
101pub fn check_linestring<T: Linestring>() {}
102
103/// Call this in a unit test next to your type definition to surface
104/// adaptation errors close to the source rather than at the algorithm
105/// call site.
106///
107/// Mirrors `boost::geometry::concepts::check<Ring>()` driven by
108/// `boost/geometry/geometries/concepts/ring_concept.hpp`.
109///
110/// # Examples
111///
112/// ```
113/// use geometry_trait::check_ring;
114/// fn _call<R: geometry_trait::Ring>() { check_ring::<R>(); }
115/// ```
116pub fn check_ring<T: Ring>() {}
117
118/// Call this in a unit test next to your type definition to surface
119/// adaptation errors close to the source rather than at the algorithm
120/// call site.
121///
122/// Mirrors `boost::geometry::concepts::check<Polygon>()` driven by
123/// `boost/geometry/geometries/concepts/polygon_concept.hpp`.
124///
125/// # Examples
126///
127/// ```
128/// use geometry_trait::check_polygon;
129/// fn _call<P: geometry_trait::Polygon>() { check_polygon::<P>(); }
130/// ```
131pub fn check_polygon<T: Polygon>() {}
132
133/// Call this in a unit test next to your type definition to surface
134/// adaptation errors close to the source rather than at the algorithm
135/// call site.
136///
137/// Mirrors `boost::geometry::concepts::check<MultiPoint>()` driven by
138/// `boost/geometry/geometries/concepts/multi_point_concept.hpp`.
139///
140/// # Examples
141///
142/// ```
143/// use geometry_trait::check_multi_point;
144/// fn _call<M: geometry_trait::MultiPoint>() { check_multi_point::<M>(); }
145/// ```
146pub fn check_multi_point<T: MultiPoint>() {}
147
148/// Call this in a unit test next to your type definition to surface
149/// adaptation errors close to the source rather than at the algorithm
150/// call site.
151///
152/// Mirrors `boost::geometry::concepts::check<MultiLinestring>()`
153/// driven by
154/// `boost/geometry/geometries/concepts/multi_linestring_concept.hpp`.
155///
156/// # Examples
157///
158/// ```
159/// use geometry_trait::check_multi_linestring;
160/// fn _call<M: geometry_trait::MultiLinestring>() { check_multi_linestring::<M>(); }
161/// ```
162pub fn check_multi_linestring<T: MultiLinestring>() {}
163
164/// Call this in a unit test next to your type definition to surface
165/// adaptation errors close to the source rather than at the algorithm
166/// call site.
167///
168/// Mirrors `boost::geometry::concepts::check<MultiPolygon>()` driven
169/// by `boost/geometry/geometries/concepts/multi_polygon_concept.hpp`.
170///
171/// # Examples
172///
173/// ```
174/// use geometry_trait::check_multi_polygon;
175/// fn _call<M: geometry_trait::MultiPolygon>() { check_multi_polygon::<M>(); }
176/// ```
177pub fn check_multi_polygon<T: MultiPolygon>() {}
178
179/// Call this in a unit test next to your type definition to surface
180/// adaptation errors close to the source rather than at the algorithm
181/// call site.
182///
183/// Mirrors the geometry-collection arm of
184/// `boost::geometry::concepts::check<T>()` (see
185/// `boost/geometry/geometries/concepts/check.hpp`).
186///
187/// # Examples
188///
189/// ```
190/// use geometry_trait::check_geometry_collection;
191/// fn _call<C: geometry_trait::GeometryCollection>() { check_geometry_collection::<C>(); }
192/// ```
193pub fn check_geometry_collection<T: GeometryCollection>() {}
194
195/// Call this in a unit test next to your type definition to surface
196/// adaptation errors close to the source rather than at the algorithm
197/// call site.
198///
199/// Mirrors the polyhedral-surface arm of
200/// `boost::geometry::concepts::check<T>()` (see
201/// `boost/geometry/geometries/concepts/check.hpp`).
202///
203/// # Examples
204///
205/// ```
206/// use geometry_trait::check_polyhedral_surface;
207/// fn _call<P: geometry_trait::PolyhedralSurface>() { check_polyhedral_surface::<P>(); }
208/// ```
209pub fn check_polyhedral_surface<T: PolyhedralSurface>() {}
210
211/// Call this in a unit test next to your type definition to surface
212/// adaptation errors close to the source rather than at the algorithm
213/// call site.
214///
215/// Generic checker for impls of [`IndexedAccess`] — useful when a
216/// custom geometry needs the `(I, D)` two-axis access but is neither a
217/// [`Box`] nor a [`Segment`].
218///
219/// # Examples
220///
221/// ```
222/// use geometry_trait::check_indexed_access;
223/// fn _call<G: geometry_trait::IndexedAccess>() { check_indexed_access::<G>(); }
224/// ```
225pub fn check_indexed_access<T: IndexedAccess>() {}