1use crate::{coord, CoordNum, Point};
2
3#[derive(Eq, PartialEq, Clone, Copy, Hash, Default)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct Coord<T: CoordNum = f64> {
26 pub x: T,
29 pub y: T,
32}
33
34#[deprecated(note = "Renamed to `geo_types::Coord` (or `geo::Coord`)")]
35pub type Coordinate<T = f64> = Coord<T>;
36
37impl<T: CoordNum> From<(T, T)> for Coord<T> {
38 #[inline]
39 fn from(coords: (T, T)) -> Self {
40 coord! {
41 x: coords.0,
42 y: coords.1,
43 }
44 }
45}
46
47impl<T: CoordNum> From<[T; 2]> for Coord<T> {
48 #[inline]
49 fn from(coords: [T; 2]) -> Self {
50 coord! {
51 x: coords[0],
52 y: coords[1],
53 }
54 }
55}
56
57impl<T: CoordNum> From<Point<T>> for Coord<T> {
58 #[inline]
59 fn from(point: Point<T>) -> Self {
60 coord! {
61 x: point.x(),
62 y: point.y(),
63 }
64 }
65}
66
67impl<T: CoordNum> From<Coord<T>> for (T, T) {
68 #[inline]
69 fn from(coord: Coord<T>) -> Self {
70 (coord.x, coord.y)
71 }
72}
73
74impl<T: CoordNum> From<Coord<T>> for [T; 2] {
75 #[inline]
76 fn from(coord: Coord<T>) -> Self {
77 [coord.x, coord.y]
78 }
79}
80
81impl<T: CoordNum> Coord<T> {
82 #[inline]
99 pub fn x_y(&self) -> (T, T) {
100 (self.x, self.y)
101 }
102}
103
104use core::ops::{Add, Div, Mul, Neg, Sub};
105
106impl<T> Neg for Coord<T>
120where
121 T: CoordNum + Neg<Output = T>,
122{
123 type Output = Self;
124
125 #[inline]
126 fn neg(self) -> Self {
127 coord! {
128 x: -self.x,
129 y: -self.y,
130 }
131 }
132}
133
134impl<T: CoordNum> Add for Coord<T> {
149 type Output = Self;
150
151 #[inline]
152 fn add(self, rhs: Self) -> Self {
153 coord! {
154 x: self.x + rhs.x,
155 y: self.y + rhs.y,
156 }
157 }
158}
159
160impl<T: CoordNum> Sub for Coord<T> {
175 type Output = Self;
176
177 #[inline]
178 fn sub(self, rhs: Self) -> Self {
179 coord! {
180 x: self.x - rhs.x,
181 y: self.y - rhs.y,
182 }
183 }
184}
185
186impl<T: CoordNum> Mul<T> for Coord<T> {
200 type Output = Self;
201
202 #[inline]
203 fn mul(self, rhs: T) -> Self {
204 coord! {
205 x: self.x * rhs,
206 y: self.y * rhs,
207 }
208 }
209}
210
211impl<T: CoordNum> Div<T> for Coord<T> {
225 type Output = Self;
226
227 #[inline]
228 fn div(self, rhs: T) -> Self {
229 coord! {
230 x: self.x / rhs,
231 y: self.y / rhs,
232 }
233 }
234}
235
236use num_traits::Zero;
237impl<T: CoordNum> Coord<T> {
251 #[inline]
252 pub fn zero() -> Self {
253 coord! {
254 x: T::zero(),
255 y: T::zero(),
256 }
257 }
258}
259
260impl<T: CoordNum> Zero for Coord<T> {
261 #[inline]
262 fn zero() -> Self {
263 Self::zero()
264 }
265 #[inline]
266 fn is_zero(&self) -> bool {
267 self.x.is_zero() && self.y.is_zero()
268 }
269}
270
271#[cfg(any(feature = "approx", test))]
272mod approx_integration {
273 use super::*;
274 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
275
276 impl<T> AbsDiffEq for Coord<T>
277 where
278 T: CoordNum + AbsDiffEq<Epsilon = T>,
279 {
280 type Epsilon = T::Epsilon;
281
282 #[inline]
283 fn default_epsilon() -> T::Epsilon {
284 T::default_epsilon()
285 }
286
287 #[inline]
288 fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
289 T::abs_diff_eq(&self.x, &other.x, epsilon) && T::abs_diff_eq(&self.y, &other.y, epsilon)
290 }
291 }
292
293 impl<T> RelativeEq for Coord<T>
294 where
295 T: CoordNum + RelativeEq<Epsilon = T>,
296 {
297 #[inline]
298 fn default_max_relative() -> T::Epsilon {
299 T::default_max_relative()
300 }
301
302 #[inline]
303 fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
304 T::relative_eq(&self.x, &other.x, epsilon, max_relative)
305 && T::relative_eq(&self.y, &other.y, epsilon, max_relative)
306 }
307 }
308
309 impl<T> UlpsEq for Coord<T>
310 where
311 T: CoordNum + UlpsEq<Epsilon = T>,
312 {
313 #[inline]
314 fn default_max_ulps() -> u32 {
315 T::default_max_ulps()
316 }
317
318 #[inline]
319 fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
320 T::ulps_eq(&self.x, &other.x, epsilon, max_ulps)
321 && T::ulps_eq(&self.y, &other.y, epsilon, max_ulps)
322 }
323 }
324}
325
326#[cfg(feature = "rstar_0_8")]
327impl<T> ::rstar_0_8::Point for Coord<T>
328where
329 T: ::num_traits::Float + ::rstar_0_8::RTreeNum,
330{
331 type Scalar = T;
332
333 const DIMENSIONS: usize = 2;
334
335 #[inline]
336 fn generate(generator: impl Fn(usize) -> Self::Scalar) -> Self {
337 coord! {
338 x: generator(0),
339 y: generator(1),
340 }
341 }
342
343 #[inline]
344 fn nth(&self, index: usize) -> Self::Scalar {
345 match index {
346 0 => self.x,
347 1 => self.y,
348 _ => unreachable!(),
349 }
350 }
351
352 #[inline]
353 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
354 match index {
355 0 => &mut self.x,
356 1 => &mut self.y,
357 _ => unreachable!(),
358 }
359 }
360}
361
362#[cfg(feature = "rstar_0_9")]
363impl<T> ::rstar_0_9::Point for Coord<T>
364where
365 T: ::num_traits::Float + ::rstar_0_9::RTreeNum,
366{
367 type Scalar = T;
368
369 const DIMENSIONS: usize = 2;
370
371 #[inline]
372 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
373 coord! {
374 x: generator(0),
375 y: generator(1),
376 }
377 }
378
379 #[inline]
380 fn nth(&self, index: usize) -> Self::Scalar {
381 match index {
382 0 => self.x,
383 1 => self.y,
384 _ => unreachable!(),
385 }
386 }
387
388 #[inline]
389 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
390 match index {
391 0 => &mut self.x,
392 1 => &mut self.y,
393 _ => unreachable!(),
394 }
395 }
396}
397
398#[cfg(feature = "rstar_0_10")]
399impl<T> ::rstar_0_10::Point for Coord<T>
400where
401 T: ::num_traits::Float + ::rstar_0_10::RTreeNum,
402{
403 type Scalar = T;
404
405 const DIMENSIONS: usize = 2;
406
407 #[inline]
408 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
409 coord! {
410 x: generator(0),
411 y: generator(1),
412 }
413 }
414
415 #[inline]
416 fn nth(&self, index: usize) -> Self::Scalar {
417 match index {
418 0 => self.x,
419 1 => self.y,
420 _ => unreachable!(),
421 }
422 }
423
424 #[inline]
425 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
426 match index {
427 0 => &mut self.x,
428 1 => &mut self.y,
429 _ => unreachable!(),
430 }
431 }
432}
433
434#[cfg(feature = "rstar_0_11")]
435impl<T> ::rstar_0_11::Point for Coord<T>
436where
437 T: ::num_traits::Float + ::rstar_0_11::RTreeNum,
438{
439 type Scalar = T;
440
441 const DIMENSIONS: usize = 2;
442
443 #[inline]
444 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
445 coord! {
446 x: generator(0),
447 y: generator(1),
448 }
449 }
450
451 #[inline]
452 fn nth(&self, index: usize) -> Self::Scalar {
453 match index {
454 0 => self.x,
455 1 => self.y,
456 _ => unreachable!(),
457 }
458 }
459
460 #[inline]
461 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
462 match index {
463 0 => &mut self.x,
464 1 => &mut self.y,
465 _ => unreachable!(),
466 }
467 }
468}
469
470#[cfg(feature = "rstar_0_12")]
471impl<T> ::rstar_0_12::Point for Coord<T>
472where
473 T: ::num_traits::Float + ::rstar_0_12::RTreeNum,
474{
475 type Scalar = T;
476
477 const DIMENSIONS: usize = 2;
478
479 #[inline]
480 fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
481 coord! {
482 x: generator(0),
483 y: generator(1),
484 }
485 }
486
487 #[inline]
488 fn nth(&self, index: usize) -> Self::Scalar {
489 match index {
490 0 => self.x,
491 1 => self.y,
492 _ => unreachable!(),
493 }
494 }
495
496 #[inline]
497 fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
498 match index {
499 0 => &mut self.x,
500 1 => &mut self.y,
501 _ => unreachable!(),
502 }
503 }
504}
505
506impl<T: CoordNum> AsRef<Coord<T>> for Coord<T> {
507 fn as_ref(&self) -> &Coord<T> {
508 self
509 }
510}