postgres_types_extra/
pg_point.rs

1use bytes::{Buf, BufMut};
2use postgres_types::{FromSql, IsNull, ToSql, Type, accepts, to_sql_checked};
3use std::{error::Error, fmt};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct PgPoint {
7    pub x: f64,
8    pub y: f64,
9}
10
11impl fmt::Display for PgPoint {
12    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13        write!(f, "({},{})", self.x, self.y)
14    }
15}
16
17impl FromSql<'_> for PgPoint {
18    fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
19        if ty.name() != "point" {
20            return Err("Unexpected type".into());
21        }
22        let x = raw.get_f64();
23        let y = raw.get_f64();
24        Ok(PgPoint { x, y })
25    }
26
27    accepts!(POINT);
28}
29
30impl ToSql for PgPoint {
31    fn to_sql(
32        &self,
33        ty: &Type,
34        out: &mut bytes::BytesMut,
35    ) -> Result<postgres_types::IsNull, Box<dyn Error + Sync + Send>>
36    where
37        Self: Sized,
38    {
39        if ty.name() != "point" {
40            return Err("Unexpected type".into());
41        }
42
43        out.put_f64(self.x);
44        out.put_f64(self.y);
45
46        Ok(IsNull::No)
47    }
48
49    accepts!(POINT);
50
51    to_sql_checked!();
52}