Skip to content

Commit 0d596ed

Browse files
author
AGAEV Denis E
committed
Add ToSQL traits for geo types
1 parent 5f6eead commit 0d596ed

File tree

1 file changed

+76
-3
lines changed

1 file changed

+76
-3
lines changed

src/additional_types.rs

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use byteorder::{BigEndian, ReadBytesExt};
2+
use bytes::{BufMut, BytesMut};
23
use geo_types::{coord, Coord, CoordFloat, CoordNum, Line, LineString, Polygon};
34
use itertools::Itertools;
45
use macaddr::{MacAddr6, MacAddr8};
6+
use postgres_protocol::types;
7+
use postgres_types::{to_sql_checked, IsNull, ToSql};
58
use tokio_postgres::types::{FromSql, Type};
69

710
macro_rules! build_additional_rust_type {
@@ -67,11 +70,34 @@ impl<'a> FromSql<'a> for RustMacAddr8 {
6770
build_additional_rust_type!(RustLine, Line);
6871
build_additional_rust_type!(RustPolygon, Polygon);
6972

73+
impl ToSql for RustLine {
74+
fn to_sql(
75+
&self,
76+
_: &Type,
77+
out: &mut BytesMut,
78+
) -> Result<IsNull, Box<dyn std::error::Error + Sync + Send>> {
79+
types::box_to_sql(
80+
self.inner.start.x,
81+
self.inner.start.y,
82+
self.inner.end.x,
83+
self.inner.end.y,
84+
out,
85+
);
86+
Ok(IsNull::No)
87+
}
88+
89+
to_sql_checked!();
90+
91+
fn accepts(_ty: &Type) -> bool {
92+
true
93+
}
94+
}
95+
7096
impl<'a> FromSql<'a> for RustLine {
7197
fn from_sql(
7298
_ty: &Type,
7399
raw: &'a [u8],
74-
) -> Result<RustLine, Box<dyn std::error::Error + Sync + Send>> {
100+
) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
75101
if raw.len() != 4 {
76102
return Err("Cannot convert PostgreSQL LINE into rust Line".into());
77103
}
@@ -97,11 +123,38 @@ impl<'a> FromSql<'a> for RustLine {
97123
}
98124
}
99125

126+
impl ToSql for RustPolygon {
127+
fn to_sql(
128+
&self,
129+
_: &Type,
130+
out: &mut BytesMut,
131+
) -> Result<IsNull, Box<dyn std::error::Error + Sync + Send>> {
132+
for (x, y) in self
133+
.inner
134+
.exterior()
135+
.0
136+
.iter()
137+
.map(|coordinate| (coordinate.x, coordinate.y))
138+
{
139+
out.put_f64(x);
140+
out.put_f64(y);
141+
}
142+
143+
Ok(IsNull::No)
144+
}
145+
146+
to_sql_checked!();
147+
148+
fn accepts(_ty: &Type) -> bool {
149+
true
150+
}
151+
}
152+
100153
impl<'a> FromSql<'a> for RustPolygon {
101154
fn from_sql(
102155
_ty: &Type,
103156
raw: &'a [u8],
104-
) -> Result<RustPolygon, Box<dyn std::error::Error + Sync + Send>> {
157+
) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
105158
if raw.len() % 2 != 0 {
106159
return Err("Cannot convert PostgreSQL POLYGON into rust Polygon".into());
107160
}
@@ -188,11 +241,31 @@ impl<T: CoordFloat> Circle<T> {
188241
}
189242
}
190243

244+
impl ToSql for Circle {
245+
fn to_sql(
246+
&self,
247+
_: &Type,
248+
out: &mut BytesMut,
249+
) -> Result<IsNull, Box<dyn std::error::Error + Sync + Send>> {
250+
out.put_f64(self.center.x);
251+
out.put_f64(self.center.y);
252+
out.put_f64(self.radius);
253+
254+
Ok(IsNull::No)
255+
}
256+
257+
to_sql_checked!();
258+
259+
fn accepts(_ty: &Type) -> bool {
260+
true
261+
}
262+
}
263+
191264
impl<'a> FromSql<'a> for Circle {
192265
fn from_sql(
193266
_ty: &Type,
194267
raw: &'a [u8],
195-
) -> Result<Circle, Box<dyn std::error::Error + Sync + Send>> {
268+
) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
196269
if raw.len() != 3 {
197270
return Err("Cannot convert PostgreSQL CIRCLE into rust Circle".into());
198271
}

0 commit comments

Comments
 (0)