Skip to content

Commit ce4df2b

Browse files
pkaandelf
authored andcommitted
TWKB output for remaining types
1 parent 29b52ed commit ce4df2b

File tree

2 files changed

+155
-18
lines changed

2 files changed

+155
-18
lines changed

src/postgis.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,42 @@ macro_rules! accepts_bytea {
167167
impl FromSql for twkb::Point {
168168
accepts_bytea!();
169169
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::Point> {
170-
twkb::Point::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to POINT", ty).into(); postgres::error::Error::Conversion(err)})
170+
twkb::Point::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to Point", ty).into(); postgres::error::Error::Conversion(err)})
171171
}
172172
}
173173

174174
impl FromSql for twkb::LineString {
175175
accepts_bytea!();
176176
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::LineString> {
177-
twkb::LineString::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to POINT", ty).into(); postgres::error::Error::Conversion(err)})
177+
twkb::LineString::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to LineString", ty).into(); postgres::error::Error::Conversion(err)})
178+
}
179+
}
180+
181+
impl FromSql for twkb::Polygon {
182+
accepts_bytea!();
183+
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::Polygon> {
184+
twkb::Polygon::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to Polygon", ty).into(); postgres::error::Error::Conversion(err)})
185+
}
186+
}
187+
188+
impl FromSql for twkb::MultiPoint {
189+
accepts_bytea!();
190+
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::MultiPoint> {
191+
twkb::MultiPoint::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to MultiPoint", ty).into(); postgres::error::Error::Conversion(err)})
192+
}
193+
}
194+
195+
impl FromSql for twkb::MultiLineString {
196+
accepts_bytea!();
197+
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::MultiLineString> {
198+
twkb::MultiLineString::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to MultiLineString", ty).into(); postgres::error::Error::Conversion(err)})
199+
}
200+
}
201+
202+
impl FromSql for twkb::MultiPolygon {
203+
accepts_bytea!();
204+
fn from_sql<R: Read>(ty: &Type, raw: &mut R, _ctx: &SessionInfo) -> postgres::Result<twkb::MultiPolygon> {
205+
twkb::MultiPolygon::read_twkb(raw).map_err(|_| {let err: Box<std::error::Error + Sync + Send> = format!("cannot convert {} to MultiPolygon", ty).into(); postgres::error::Error::Conversion(err)})
178206
}
179207
}
180208

src/twkb.rs

Lines changed: 125 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use types as postgis;
2-
use ewkb::{AsEwkbPoint, EwkbPoint, AsEwkbLineString, EwkbLineString};
2+
use ewkb;
33
use std::io::prelude::*;
44
use std::mem;
55
use std::fmt;
@@ -217,9 +217,9 @@ impl TwkbGeom for Point {
217217
}
218218
}
219219

220-
impl<'a> AsEwkbPoint<'a> for Point {
221-
fn as_ewkb(&'a self) -> EwkbPoint<'a> {
222-
EwkbPoint { geom: self, srid: None, point_type: postgis::PointType::Point }
220+
impl<'a> ewkb::AsEwkbPoint<'a> for Point {
221+
fn as_ewkb(&'a self) -> ewkb::EwkbPoint<'a> {
222+
ewkb::EwkbPoint { geom: self, srid: None, point_type: postgis::PointType::Point }
223223
}
224224
}
225225

@@ -246,6 +246,23 @@ impl TwkbGeom for LineString {
246246
}
247247
}
248248

249+
impl<'a> postgis::LineString<'a> for LineString {
250+
type ItemType = Point;
251+
type Iter = Iter<'a, Self::ItemType>;
252+
fn points(&'a self) -> Self::Iter {
253+
self.points.iter()
254+
}
255+
}
256+
257+
impl<'a> ewkb::AsEwkbLineString<'a> for LineString {
258+
type PointType = Point;
259+
type Iter = Iter<'a, Point>;
260+
fn as_ewkb(&'a self) -> ewkb::EwkbLineString<'a, Self::PointType, Self::Iter> {
261+
ewkb::EwkbLineString { geom: self, srid: None, point_type: postgis::PointType::Point }
262+
}
263+
}
264+
265+
249266
impl TwkbGeom for Polygon {
250267
fn read_twkb_body<R: Read>(raw: &mut R, twkb_info: &TwkbInfo) -> Result<Self, Error> {
251268
// nrings uvarint
@@ -281,6 +298,24 @@ impl TwkbGeom for Polygon {
281298
}
282299
}
283300

301+
impl<'a> postgis::Polygon<'a> for Polygon {
302+
type ItemType = LineString;
303+
type Iter = Iter<'a, Self::ItemType>;
304+
fn rings(&'a self) -> Self::Iter {
305+
self.rings.iter()
306+
}
307+
}
308+
309+
impl<'a> ewkb::AsEwkbPolygon<'a> for Polygon {
310+
type PointType = Point;
311+
type PointIter = Iter<'a, Point>;
312+
type ItemType = LineString;
313+
type Iter = Iter<'a, Self::ItemType>;
314+
fn as_ewkb(&'a self) -> ewkb::EwkbPolygon<'a, Self::PointType, Self::PointIter, Self::ItemType, Self::Iter> {
315+
ewkb::EwkbPolygon { geom: self, srid: None, point_type: postgis::PointType::Point }
316+
}
317+
}
318+
284319

285320
impl TwkbGeom for MultiPoint {
286321
fn read_twkb_body<R: Read>(raw: &mut R, twkb_info: &TwkbInfo) -> Result<Self, Error> {
@@ -312,6 +347,23 @@ impl TwkbGeom for MultiPoint {
312347
}
313348
}
314349

350+
impl<'a> postgis::MultiPoint<'a> for MultiPoint {
351+
type ItemType = Point;
352+
type Iter = Iter<'a, Self::ItemType>;
353+
fn points(&'a self) -> Self::Iter {
354+
self.points.iter()
355+
}
356+
}
357+
358+
impl<'a> ewkb::AsEwkbMultiPoint<'a> for MultiPoint {
359+
type PointType = Point;
360+
type Iter = Iter<'a, Point>;
361+
fn as_ewkb(&'a self) -> ewkb::EwkbMultiPoint<'a, Self::PointType, Self::Iter> {
362+
ewkb::EwkbMultiPoint { geom: self, srid: None, point_type: postgis::PointType::Point }
363+
}
364+
}
365+
366+
315367
impl TwkbGeom for MultiLineString {
316368
fn read_twkb_body<R: Read>(raw: &mut R, twkb_info: &TwkbInfo) -> Result<Self, Error> {
317369
// nlinestrings uvarint
@@ -350,6 +402,25 @@ impl TwkbGeom for MultiLineString {
350402
}
351403
}
352404

405+
impl<'a> postgis::MultiLineString<'a> for MultiLineString {
406+
type ItemType = LineString;
407+
type Iter = Iter<'a, Self::ItemType>;
408+
fn lines(&'a self) -> Self::Iter {
409+
self.lines.iter()
410+
}
411+
}
412+
413+
impl<'a> ewkb::AsEwkbMultiLineString<'a> for MultiLineString {
414+
type PointType = Point;
415+
type PointIter = Iter<'a, Point>;
416+
type ItemType = LineString;
417+
type Iter = Iter<'a, Self::ItemType>;
418+
fn as_ewkb(&'a self) -> ewkb::EwkbMultiLineString<'a, Self::PointType, Self::PointIter, Self::ItemType, Self::Iter> {
419+
ewkb::EwkbMultiLineString { geom: self, srid: None, point_type: postgis::PointType::Point }
420+
}
421+
}
422+
423+
353424
impl TwkbGeom for MultiPolygon {
354425
fn read_twkb_body<R: Read>(raw: &mut R, twkb_info: &TwkbInfo) -> Result<Self, Error> {
355426
// npolygons uvarint
@@ -401,27 +472,29 @@ impl TwkbGeom for MultiPolygon {
401472
}
402473
}
403474

404-
405-
impl<'a> AsEwkbLineString<'a> for LineString {
406-
type PointType = Point;
407-
type Iter = Iter<'a, Point>;
408-
fn as_ewkb(&'a self) -> EwkbLineString<'a, Self::PointType, Self::Iter> {
409-
EwkbLineString { geom: self, srid: None, point_type: postgis::PointType::Point }
475+
impl<'a> postgis::MultiPolygon<'a> for MultiPolygon {
476+
type ItemType = Polygon;
477+
type Iter = Iter<'a, Self::ItemType>;
478+
fn polygons(&'a self) -> Self::Iter {
479+
self.polygons.iter()
410480
}
411481
}
412482

413-
414-
impl<'a> postgis::LineString<'a> for LineString {
415-
type ItemType = Point;
483+
impl<'a> ewkb::AsEwkbMultiPolygon<'a> for MultiPolygon {
484+
type PointType = Point;
485+
type PointIter = Iter<'a, Point>;
486+
type LineType = LineString;
487+
type LineIter = Iter<'a, Self::LineType>;
488+
type ItemType = Polygon;
416489
type Iter = Iter<'a, Self::ItemType>;
417-
fn points(&'a self) -> Self::Iter {
418-
self.points.iter()
490+
fn as_ewkb(&'a self) -> ewkb::EwkbMultiPolygon<'a, Self::PointType, Self::PointIter, Self::LineType, Self::LineIter, Self::ItemType, Self::Iter> {
491+
ewkb::EwkbMultiPolygon { geom: self, srid: None, point_type: postgis::PointType::Point }
419492
}
420493
}
421494

422495

423496
#[cfg(test)]
424-
use ewkb::EwkbWrite;
497+
use ewkb::{EwkbWrite, AsEwkbPoint, AsEwkbLineString, AsEwkbPolygon, AsEwkbMultiPoint, AsEwkbMultiLineString, AsEwkbMultiPolygon};
425498

426499
#[cfg(test)]
427500
fn hex_to_vec(hexstr: &str) -> Vec<u8> {
@@ -517,3 +590,39 @@ fn test_write_line() {
517590
assert_eq!(format!("{:?}", line.as_ewkb()), "$ewkbtype");
518591
assert_eq!(line.as_ewkb().to_hex_ewkb(), "010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF");
519592
}
593+
594+
#[test]
595+
fn test_write_polygon() {
596+
let twkb = hex_to_vec("03000205000004000004030000030514141700001718000018"); // SELECT encode(ST_AsTWKB('POLYGON ((0 0, 2 0, 2 2, 0 2, 0 0),(10 10, -2 10, -2 -2, 10 -2, 10 10))'::geometry), 'hex')
597+
let polygon = Polygon::read_twkb(&mut twkb.as_slice()).unwrap();
598+
assert_eq!(format!("{:?}", polygon.as_ewkb()), "$ewkbtype");
599+
assert_eq!(polygon.as_ewkb().to_hex_ewkb(), "010300000002000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000050000000000000000002440000000000000244000000000000000C0000000000000244000000000000000C000000000000000C0000000000000244000000000000000C000000000000024400000000000002440");
600+
}
601+
602+
#[test]
603+
fn test_write_multipoint() {
604+
let twkb = hex_to_vec("04000214271326"); // SELECT encode(ST_AsTWKB('MULTIPOINT ((10 -20), (0 -0.5))'::geometry), 'hex')
605+
let multipoint = MultiPoint::read_twkb(&mut twkb.as_slice()).unwrap();
606+
assert_eq!(format!("{:?}", multipoint.as_ewkb()), "$ewkbtype");
607+
//assert_eq!(multipoint.as_ewkb().to_hex_ewkb(), "0104000000020000000101000000000000000000244000000000000034C001010000000000000000000000000000000000E0BF");
608+
// "MULTIPOINT(10 -20,0 -1)"
609+
assert_eq!(multipoint.as_ewkb().to_hex_ewkb(), "0104000000020000000101000000000000000000244000000000000034C001010000000000000000000000000000000000F0BF");
610+
}
611+
612+
#[test]
613+
fn test_write_multiline() {
614+
let twkb = hex_to_vec("05000202142713260200020400"); // SELECT encode(ST_AsTWKB('MULTILINESTRING ((10 -20, 0 -0.5), (0 0, 2 0))'::geometry), 'hex')
615+
let multiline = MultiLineString::read_twkb(&mut twkb.as_slice()).unwrap();
616+
assert_eq!(format!("{:?}", multiline.as_ewkb()), "$ewkbtype");
617+
//assert_eq!(multiline.as_ewkb().to_hex_ewkb(), "010500000002000000010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF0102000000020000000000000000000000000000000000000000000000000000400000000000000000");
618+
// "MULTILINESTRING((10 -20,0 -1),(0 0,2 0))"
619+
assert_eq!(multiline.as_ewkb().to_hex_ewkb(), "010500000002000000010200000002000000000000000000244000000000000034C00000000000000000000000000000F0BF0102000000020000000000000000000000000000000000000000000000000000400000000000000000");
620+
}
621+
622+
#[test]
623+
fn test_write_multipoly() {
624+
let twkb = hex_to_vec("060002010500000400000403000003010514141700001718000018"); // SELECT encode(ST_AsTWKB('MULTIPOLYGON (((0 0, 2 0, 2 2, 0 2, 0 0)), ((10 10, -2 10, -2 -2, 10 -2, 10 10)))'::geometry), 'hex')
625+
let multipoly = MultiPolygon::read_twkb(&mut twkb.as_slice()).unwrap();
626+
assert_eq!(format!("{:?}", multipoly.as_ewkb()), "$ewkbtype");
627+
assert_eq!(multipoly.as_ewkb().to_hex_ewkb(), "010600000002000000010300000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000010300000001000000050000000000000000002440000000000000244000000000000000C0000000000000244000000000000000C000000000000000C0000000000000244000000000000000C000000000000024400000000000002440");
628+
}

0 commit comments

Comments
 (0)