1#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct Coord {
8 pub x: f64,
9 pub y: f64,
10}
11
12impl Coord {
13 pub fn new(x: f64, y: f64) -> Self {
14 Self { x, y }
15 }
16}
17
18impl From<(f64, f64)> for Coord {
19 fn from((x, y): (f64, f64)) -> Self {
20 Self { x, y }
21 }
22}
23
24impl From<Coord> for (f64, f64) {
25 fn from(c: Coord) -> Self {
26 (c.x, c.y)
27 }
28}
29
30#[cfg(feature = "geo-types")]
31impl From<geo_types::Coord<f64>> for Coord {
32 fn from(c: geo_types::Coord<f64>) -> Self {
33 Self { x: c.x, y: c.y }
34 }
35}
36
37#[cfg(feature = "geo-types")]
38impl From<Coord> for geo_types::Coord<f64> {
39 fn from(c: Coord) -> Self {
40 geo_types::Coord { x: c.x, y: c.y }
41 }
42}
43
44pub trait Transformable: Sized {
49 fn into_coord(self) -> Coord;
50 fn from_coord(c: Coord) -> Self;
51}
52
53impl Transformable for Coord {
54 fn into_coord(self) -> Coord {
55 self
56 }
57 fn from_coord(c: Coord) -> Self {
58 c
59 }
60}
61
62impl Transformable for (f64, f64) {
63 fn into_coord(self) -> Coord {
64 Coord {
65 x: self.0,
66 y: self.1,
67 }
68 }
69 fn from_coord(c: Coord) -> Self {
70 (c.x, c.y)
71 }
72}
73
74#[cfg(feature = "geo-types")]
75impl Transformable for geo_types::Coord<f64> {
76 fn into_coord(self) -> Coord {
77 Coord {
78 x: self.x,
79 y: self.y,
80 }
81 }
82 fn from_coord(c: Coord) -> Self {
83 geo_types::Coord { x: c.x, y: c.y }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn coord_from_tuple() {
93 let c: Coord = (1.0, 2.0).into();
94 assert_eq!(c.x, 1.0);
95 assert_eq!(c.y, 2.0);
96 }
97
98 #[test]
99 fn tuple_from_coord() {
100 let t: (f64, f64) = Coord::new(3.0, 4.0).into();
101 assert_eq!(t, (3.0, 4.0));
102 }
103
104 #[test]
105 fn transformable_roundtrip_tuple() {
106 let original = (10.0, 20.0);
107 let coord = original.into_coord();
108 let back = <(f64, f64)>::from_coord(coord);
109 assert_eq!(original, back);
110 }
111}