gluesql_core/data/
point.rs1use {
2 super::ValueError,
3 crate::result::{Error, Result},
4 regex::Regex,
5 serde::{Deserialize, Serialize},
6 std::fmt,
7};
8
9#[derive(Copy, Debug, Clone, Serialize, Deserialize)]
10pub struct Point {
11 pub x: f64,
12 pub y: f64,
13}
14
15impl Point {
16 pub fn new(x: f64, y: f64) -> Self {
17 Self { x, y }
18 }
19
20 pub fn from_wkt(v: &str) -> Result<Self> {
21 let re = Regex::new(r"POINT\s*\(\s*(-?\d*\.?\d+)\s+(-?\d*\.?\d+)\s*\)").unwrap();
22
23 if let Some(captures) = re.captures(v) {
24 let x = captures[1]
25 .parse::<f64>()
26 .map_err(|_| Error::Value(ValueError::FailedToParsePoint(v.to_owned())))?;
27 let y = captures[2]
28 .parse::<f64>()
29 .map_err(|_| Error::Value(ValueError::FailedToParsePoint(v.to_owned())))?;
30 Ok(Self { x, y })
31 } else {
32 Err(Error::Value(ValueError::FailedToParsePoint(v.to_owned())))
33 }
34 }
35
36 pub fn calc_distance(&self, other: &Point) -> f64 {
37 let dx = self.x - other.x;
38 let dy = self.y - other.y;
39 f64::sqrt(dx * dx + dy * dy)
40 }
41}
42
43impl PartialEq for Point {
44 fn eq(&self, other: &Self) -> bool {
45 self.x == other.x && self.y == other.y
46 }
47}
48
49impl Eq for Point {}
50
51impl fmt::Display for Point {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 write!(f, "POINT({} {})", self.x, self.y)
54 }
55}