1use crate::types::decode::Decode;
2use crate::types::encode::{Encode, IsNull};
3use crate::value::{PgValueFormat, PgValueRef};
4use rbdc::Error;
5use rbs::Value;
6use std::fmt::{Display, Formatter};
7
8#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq)]
25pub struct Point {
26 pub x: f64,
27 pub y: f64,
28}
29
30impl Display for Point {
31 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32 write!(f, "POINT({} {})", self.x, self.y)
33 }
34}
35
36impl From<Point> for Value {
37 fn from(arg: Point) -> Self {
38 rbs::Value::Ext(
39 "point",
40 Box::new(rbs::Value::Ext(
41 "point",
42 Box::new(rbs::Value::Array(vec![
43 rbs::Value::F64(arg.x),
44 rbs::Value::F64(arg.y),
45 ])),
46 )),
47 )
48 }
49}
50
51impl Decode for Point {
52 fn decode(value: PgValueRef) -> Result<Self, Error> {
53 Ok(match value.format() {
54 PgValueFormat::Binary => {
55 return Err(Error::from(
60 "POINT binary format (WKB) not supported. \
61 Use TEXT format: ST_AsText(point_column) or parse with geo-types crate.",
62 ));
63 }
64 PgValueFormat::Text => {
65 let s = value.as_str()?;
67
68 let s = s.trim();
70 if !s.starts_with("POINT(") || !s.ends_with(')') {
71 return Err(Error::from(format!(
72 "Invalid POINT format: {}. Expected 'POINT(x y)'",
73 s
74 )));
75 }
76
77 let coords = &s[6..s.len() - 1]; let parts: Vec<&str> = coords.split_whitespace().collect();
79
80 if parts.len() != 2 {
81 return Err(Error::from(format!(
82 "Invalid POINT coords: {}. Expected 2 values.",
83 coords
84 )));
85 }
86
87 let x = parts[0]
88 .parse::<f64>()
89 .map_err(|e| Error::from(format!("Invalid x coordinate: {}", e)))?;
90 let y = parts[1]
91 .parse::<f64>()
92 .map_err(|e| Error::from(format!("Invalid y coordinate: {}", e)))?;
93
94 Self { x, y }
95 }
96 })
97 }
98}
99
100impl Encode for Point {
101 fn encode(self, _buf: &mut crate::arguments::PgArgumentBuffer) -> Result<IsNull, Error> {
102 Err(Error::from(
105 "POINT encoding not supported. Use PostGIS ST_GeomFromText() or ST_MakePoint() in your query instead."
106 ))
107 }
108}