geo_types/macros.rs
1/// Creates a [`Point`] from the given coordinates.
2///
3/// ```txt
4/// point! { x: <number>, y: <number> }
5/// point!(<coordinate>)
6/// ```
7///
8/// # Examples
9///
10/// Creating a [`Point`], supplying x/y values:
11///
12/// ```
13/// use geo_types::{point, coord};
14///
15/// let p = point! { x: 181.2, y: 51.79 };
16///
17/// assert_eq!(p.x(), 181.2);
18/// assert_eq!(p.y(), 51.79);
19///
20/// let p = point!(coord! { x: 181.2, y: 51.79 });
21///
22/// assert_eq!(p.x(), 181.2);
23/// assert_eq!(p.y(), 51.79);
24/// ```
25///
26/// [`Point`]: ./struct.Point.html
27#[macro_export]
28macro_rules! point {
29 ( $($tag:tt : $val:expr),* $(,)? ) => {
30 $crate::point! ( $crate::coord! { $( $tag: $val , )* } )
31 };
32 ( $coord:expr $(,)? ) => {
33 $crate::Point::from($coord)
34 };
35}
36
37/// Creates a [`Coord`] from the given scalars.
38///
39/// ```txt
40/// coord! { x: <number>, y: <number> }
41/// ```
42///
43/// # Examples
44///
45/// Creating a [`Coord`], supplying x/y values:
46///
47/// ```
48/// use geo_types::coord;
49///
50/// let c = coord! { x: 181.2, y: 51.79 };
51///
52/// assert_eq!(c, geo_types::coord! { x: 181.2, y: 51.79 });
53/// ```
54///
55/// [`Coord`]: ./struct.Coord.html
56#[macro_export]
57macro_rules! coord {
58 (x: $x:expr, y: $y:expr $(,)* ) => {
59 $crate::Coord { x: $x, y: $y }
60 };
61}
62
63/// Creates a [`LineString`] containing the given coordinates.
64///
65/// ```txt
66/// line_string![Coord OR (x: <number>, y: <number>), …]
67/// ```
68///
69/// # Examples
70///
71/// Creating a [`LineString`], supplying x/y values:
72///
73/// ```
74/// use geo_types::line_string;
75///
76/// let ls = line_string![
77/// (x: -21.95156, y: 64.1446),
78/// (x: -21.951, y: 64.14479),
79/// (x: -21.95044, y: 64.14527),
80/// (x: -21.951445, y: 64.145508),
81/// ];
82///
83/// assert_eq!(ls[1], geo_types::coord! {
84/// x: -21.951,
85/// y: 64.14479
86/// });
87/// ```
88///
89/// Creating a [`LineString`], supplying [`Coord`]s:
90///
91/// ```
92/// use geo_types::line_string;
93///
94/// let coord1 = geo_types::coord! {
95/// x: -21.95156,
96/// y: 64.1446,
97/// };
98/// let coord2 = geo_types::coord! {
99/// x: -21.951,
100/// y: 64.14479,
101/// };
102/// let coord3 = geo_types::coord! {
103/// x: -21.95044,
104/// y: 64.14527,
105/// };
106/// let coord4 = geo_types::coord! {
107/// x: -21.951445,
108/// y: 64.145508,
109/// };
110///
111/// let ls = line_string![coord1, coord2, coord3, coord4];
112///
113/// assert_eq!(
114/// ls[1],
115/// geo_types::coord! {
116/// x: -21.951,
117/// y: 64.14479
118/// }
119/// );
120/// ```
121///
122/// [`Coord`]: ./struct.Coord.html
123/// [`LineString`]: ./line_string/struct.LineString.html
124#[macro_export]
125macro_rules! line_string {
126 () => { $crate::LineString::new($crate::_alloc::vec![]) };
127 (
128 $(( $($tag:tt : $val:expr),* $(,)? )),*
129 $(,)?
130 ) => {
131 line_string![
132 $(
133 $crate::coord! { $( $tag: $val , )* },
134 )*
135 ]
136 };
137 (
138 $($coord:expr),*
139 $(,)?
140 ) => {
141 $crate::LineString::new(
142 $crate::_alloc::vec![
143 $($coord),*
144 ]
145 )
146 };
147}
148
149/// Creates a [`Polygon`] containing the given coordinates.
150///
151/// ```txt
152/// polygon![Coord OR (x: <number>, y: <number>), …]
153///
154/// // or
155///
156/// polygon!(
157/// exterior: [Coord OR (x: <number>, y: <number>), …],
158/// interiors: [
159/// [Coord OR (x: <number>, y: <number>), …],
160/// …
161/// ],
162/// )
163/// ```
164///
165/// # Examples
166///
167/// Creating a [`Polygon`] without interior rings, supplying x/y values:
168///
169/// ```
170/// use geo_types::polygon;
171///
172/// let poly = polygon![
173/// (x: -111., y: 45.),
174/// (x: -111., y: 41.),
175/// (x: -104., y: 41.),
176/// (x: -104., y: 45.),
177/// ];
178///
179/// assert_eq!(
180/// poly.exterior()[1],
181/// geo_types::coord! { x: -111., y: 41. },
182/// );
183/// ```
184///
185/// Creating a [`Polygon`], supplying x/y values:
186///
187/// ```
188/// use geo_types::polygon;
189///
190/// let poly = polygon!(
191/// exterior: [
192/// (x: -111., y: 45.),
193/// (x: -111., y: 41.),
194/// (x: -104., y: 41.),
195/// (x: -104., y: 45.),
196/// ],
197/// interiors: [
198/// [
199/// (x: -110., y: 44.),
200/// (x: -110., y: 42.),
201/// (x: -105., y: 42.),
202/// (x: -105., y: 44.),
203/// ],
204/// ],
205/// );
206///
207/// assert_eq!(
208/// poly.exterior()[1],
209/// geo_types::coord! { x: -111., y: 41. },
210/// );
211/// ```
212///
213/// [`Coord`]: ./struct.Coord.html
214/// [`Polygon`]: ./struct.Polygon.html
215#[macro_export]
216macro_rules! polygon {
217 () => { $crate::Polygon::new($crate::line_string![], $crate::_alloc::vec![]) };
218 (
219 exterior: [
220 $(( $($exterior_tag:tt : $exterior_val:expr),* $(,)? )),*
221 $(,)?
222 ],
223 interiors: [
224 $([
225 $(( $($interior_tag:tt : $interior_val:expr),* $(,)? )),*
226 $(,)?
227 ]),*
228 $(,)?
229 ]
230 $(,)?
231 ) => {
232 polygon!(
233 exterior: [
234 $(
235 $crate::coord! { $( $exterior_tag: $exterior_val , )* },
236 )*
237 ],
238 interiors: [
239 $([
240 $($crate::coord! { $( $interior_tag: $interior_val , )* }),*
241 ]),*
242 ],
243 )
244 };
245 (
246 exterior: [
247 $($exterior_coord:expr),*
248 $(,)?
249 ],
250 interiors: [
251 $([
252 $($interior_coord:expr),*
253 $(,)?
254 ]),*
255 $(,)?
256 ]
257 $(,)?
258 ) => {
259 $crate::Polygon::new(
260 $crate::line_string![
261 $($exterior_coord), *
262 ],
263 $crate::_alloc::vec![
264 $(
265 $crate::line_string![$($interior_coord),*]
266 ), *
267 ]
268 )
269 };
270 (
271 $(( $($tag:tt : $val:expr),* $(,)? )),*
272 $(,)?
273 ) => {
274 polygon![
275 $($crate::coord! { $( $tag: $val , )* }),*
276 ]
277 };
278 (
279 $($coord:expr),*
280 $(,)?
281 ) => {
282 $crate::Polygon::new(
283 $crate::line_string![$($coord,)*],
284 $crate::_alloc::vec![],
285 )
286 };
287}
288
289#[cfg(test)]
290mod test {
291 #[test]
292 fn test_point() {
293 let p = point! { x: 1.2, y: 3.4 };
294 assert_eq!(p.x(), 1.2);
295 assert_eq!(p.y(), 3.4);
296
297 let p = point! {
298 x: 1.2,
299 y: 3.4,
300 };
301 assert_eq!(p.x(), 1.2);
302 assert_eq!(p.y(), 3.4);
303
304 let p = point!(coord! { x: 1.2, y: 3.4 });
305 assert_eq!(p.x(), 1.2);
306 assert_eq!(p.y(), 3.4);
307
308 let p = point!(coord! { x: 1.2, y: 3.4 },);
309 assert_eq!(p.x(), 1.2);
310 assert_eq!(p.y(), 3.4);
311 }
312
313 #[test]
314 fn test_line() {
315 let ls = line_string![(x: -1.2f32, y: 3.4f32)];
316 assert_eq!(ls[0], coord! { x: -1.2, y: 3.4 });
317
318 let ls = line_string![
319 (x: -1.2f32, y: 3.4f32),
320 ];
321 assert_eq!(ls[0], coord! { x: -1.2, y: 3.4 });
322
323 let ls = line_string![(
324 x: -1.2f32,
325 y: 3.4f32,
326 )];
327 assert_eq!(ls[0], coord! { x: -1.2, y: 3.4 });
328
329 let ls = line_string![
330 (x: -1.2f32, y: 3.4f32),
331 (x: -5.6, y: 7.8),
332 ];
333 assert_eq!(ls[0], coord! { x: -1.2, y: 3.4 });
334 assert_eq!(ls[1], coord! { x: -5.6, y: 7.8 });
335 }
336
337 #[test]
338 fn test_polygon() {
339 let p = polygon!(
340 exterior: [(x: 1, y: 2)],
341 interiors: [[(x: 3, y: 4)]]
342 );
343 assert_eq!(p.exterior()[0], coord! { x: 1, y: 2 });
344 assert_eq!(p.interiors()[0][0], coord! { x: 3, y: 4 });
345
346 let p = polygon!(
347 exterior: [(x: 1, y: 2)],
348 interiors: [[(x: 3, y: 4)]],
349 );
350 assert_eq!(p.exterior()[0], coord! { x: 1, y: 2 });
351 assert_eq!(p.interiors()[0][0], coord! { x: 3, y: 4 });
352
353 let p = polygon!(
354 exterior: [(x: 1, y: 2, )],
355 interiors: [[(x: 3, y: 4, )]],
356 );
357 assert_eq!(p.exterior()[0], coord! { x: 1, y: 2 });
358 assert_eq!(p.interiors()[0][0], coord! { x: 3, y: 4 });
359
360 let p = polygon!(
361 exterior: [(x: 1, y: 2, ), ],
362 interiors: [[(x: 3, y: 4, ), ]],
363 );
364 assert_eq!(p.exterior()[0], coord! { x: 1, y: 2 });
365 assert_eq!(p.interiors()[0][0], coord! { x: 3, y: 4 });
366
367 let p = polygon!(
368 exterior: [(x: 1, y: 2, ), ],
369 interiors: [[(x: 3, y: 4, ), ], ],
370 );
371 assert_eq!(p.exterior()[0], coord! { x: 1, y: 2 });
372 assert_eq!(p.interiors()[0][0], coord! { x: 3, y: 4 });
373 }
374}