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}