1mod encoding;
6use crate::{error::Error, types as postgis};
7use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
8use encoding::*;
9use std;
10use std::fmt;
11use std::io::prelude::*;
12use std::iter::FromIterator;
13use std::slice::Iter;
14
15pub mod point;
17pub use point::*;
18pub mod container;
19pub use container::point::*;
20mod geometry;
21pub use geometry::*;
22
23pub trait EwkbRead: fmt::Debug + Sized {
26 fn point_type() -> PointType;
27
28 fn read_ewkb<R: Read>(raw: &mut R) -> Result<Self, Error> {
29 let byte_order = raw.read_i8()?;
30 let is_be = byte_order == 0i8;
31
32 let type_id = read_u32(raw, is_be)?;
33 let mut srid: Option<i32> = None;
34 if type_id & 0x20000000 == 0x20000000 {
35 srid = Some(read_i32(raw, is_be)?);
36 }
37 Self::read_ewkb_body(raw, is_be, type_id, srid)
38 }
39
40 #[doc(hidden)]
41 fn read_ewkb_body<R: Read>(
42 raw: &mut R,
43 is_be: bool,
44 type_id: u32,
45 srid: Option<i32>,
46 ) -> Result<Self, Error>;
47}
48
49pub trait EwkbWrite: fmt::Debug + Sized {
50 fn opt_srid(&self) -> Option<i32> {
51 None
52 }
53
54 fn wkb_type_id(point_type: &PointType, srid: Option<i32>) -> u32 {
55 let mut type_ = 0;
56 if srid.is_some() {
57 type_ |= 0x20000000;
58 }
59 if *point_type == PointType::PointZ || *point_type == PointType::PointZM {
60 type_ |= 0x80000000;
61 }
62 if *point_type == PointType::PointM || *point_type == PointType::PointZM {
63 type_ |= 0x40000000;
64 }
65 type_
66 }
67
68 fn type_id(&self) -> u32;
69
70 fn write_ewkb<W: Write + ?Sized>(&self, w: &mut W) -> Result<(), Error> {
71 w.write_u8(0x01)?;
73 let type_id = self.type_id();
74 w.write_u32::<LittleEndian>(type_id)?;
75 self.opt_srid()
76 .map(|srid| w.write_i32::<LittleEndian>(srid));
77 self.write_ewkb_body(w)?;
78 Ok(())
79 }
80 #[doc(hidden)]
81 fn write_ewkb_body<W: Write + ?Sized>(&self, w: &mut W) -> Result<(), Error>;
82
83 fn to_hex_ewkb(&self) -> String {
84 let mut buf: Vec<u8> = Vec::new();
85 self.write_ewkb(&mut buf).unwrap();
86 let hex: String = buf
87 .iter()
88 .fold(String::new(), |s, &b| s + &format!("{:02X}", b));
89 hex
90 }
91}
92
93impl From<std::io::Error> for Error {
96 fn from(e: std::io::Error) -> Error {
97 Error::Read(format!("error while reading: {:?}", e))
98 }
99}
100
101fn has_z(type_id: u32) -> bool {
104 type_id & 0x80000000 == 0x80000000
105}
106fn has_m(type_id: u32) -> bool {
107 type_id & 0x40000000 == 0x40000000
108}
109
110#[test]
111#[rustfmt::skip]
112fn test_point_write() {
113 let point = Point::new(10.0, -20.0, None);
115 assert_eq!(point.as_ewkb().to_hex_ewkb(), "0101000000000000000000244000000000000034C0");
116
117 let point = PointZ { x: 10.0, y: -20.0, z: 100.0, srid: None };
119 assert_eq!(point.as_ewkb().to_hex_ewkb(), "0101000080000000000000244000000000000034C00000000000005940");
120
121 let point = PointM { x: 10.0, y: -20.0, m: 1.0, srid: None };
123 assert_eq!(point.as_ewkb().to_hex_ewkb(), "0101000040000000000000244000000000000034C0000000000000F03F");
124
125 let point = PointZM { x: 10.0, y: -20.0, z: 100.0, m: 1.0, srid: None };
127 assert_eq!(point.as_ewkb().to_hex_ewkb(), "01010000C0000000000000244000000000000034C00000000000005940000000000000F03F");
128
129 let point = Point::new(0.0, -1.0, None);
131 assert_eq!(point.as_ewkb().to_hex_ewkb(), "01010000000000000000000000000000000000F0BF");
132 let point = Point::new(10.0, -20.0, Some(4326));
136 assert_eq!(point.as_ewkb().to_hex_ewkb(), "0101000020E6100000000000000000244000000000000034C0");
137}
138
139#[test]
140#[rustfmt::skip]
141fn test_line_write() {
142 let p = |x, y| Point::new(x, y, None);
143 let line = LineStringT::<Point> {srid: None, points: vec![p(10.0, -20.0), p(0., -0.5)]};
145 assert_eq!(line.as_ewkb().to_hex_ewkb(), "010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF");
146
147 let line = LineStringT::<Point> {srid: Some(4326), points: vec![p(10.0, -20.0), p(0., -0.5)]};
149 assert_eq!(line.as_ewkb().to_hex_ewkb(), "0102000020E610000002000000000000000000244000000000000034C00000000000000000000000000000E0BF");
150
151 let p = |x, y, z| PointZ { x, y, z, srid: Some(4326) };
152 let line = LineStringT::<PointZ> {srid: Some(4326), points: vec![p(10.0, -20.0, 100.0), p(0., -0.5, 101.0)]};
154 assert_eq!(line.as_ewkb().to_hex_ewkb(), "01020000A0E610000002000000000000000000244000000000000034C000000000000059400000000000000000000000000000E0BF0000000000405940");
155}
156
157#[test]
158#[rustfmt::skip]
159fn test_polygon_write() {
160 let p = |x, y| Point::new(x, y, Some(4326));
161 let line = LineStringT::<Point> {srid: Some(4326), points: vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]};
163 let poly = PolygonT::<Point> {srid: Some(4326), rings: vec![line]};
164 assert_eq!(poly.as_ewkb().to_hex_ewkb(), "0103000020E610000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000");
165}
166
167#[test]
168#[rustfmt::skip]
169fn test_multipoint_write() {
170 let p = |x, y, z| PointZ { x, y, z, srid: Some(4326) };
171 let points = MultiPointT::<PointZ> {srid: Some(4326), points: vec![p(10.0, -20.0, 100.0), p(0., -0.5, 101.0)]};
173 assert_eq!(points.as_ewkb().to_hex_ewkb(), "01040000A0E6100000020000000101000080000000000000244000000000000034C0000000000000594001010000800000000000000000000000000000E0BF0000000000405940");
174}
175
176#[test]
177#[rustfmt::skip]
178fn test_multiline_write() {
179 let p = |x, y| Point::new(x, y, Some(4326));
180 let line1 = LineStringT::<Point> {srid: Some(4326), points: vec![p(10.0, -20.0), p(0., -0.5)]};
182 let line2 = LineStringT::<Point> {srid: Some(4326), points: vec![p(0., 0.), p(2., 0.)]};
183 let multiline = MultiLineStringT::<Point> {srid: Some(4326),lines: vec![line1, line2]};
184 assert_eq!(multiline.as_ewkb().to_hex_ewkb(), "0105000020E610000002000000010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF0102000000020000000000000000000000000000000000000000000000000000400000000000000000");
185}
186
187#[test]
188#[rustfmt::skip]
189fn test_multipolygon_write() {
190 let p = |x, y| Point::new(x, y, Some(4326));
191 let line = LineStringT::<Point> {srid: Some(4326), points: vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]};
193 let poly1 = PolygonT::<Point> {srid: Some(4326), rings: vec![line]};
194 let line = LineStringT::<Point> {srid: Some(4326), points: vec![p(10., 10.), p(-2., 10.), p(-2., -2.), p(10., -2.), p(10., 10.)]};
195 let poly2 = PolygonT::<Point> {srid: Some(4326), rings: vec![line]};
196 let multipoly = MultiPolygonT::<Point> {srid: Some(4326), polygons: vec![poly1, poly2]};
197 assert_eq!(multipoly.as_ewkb().to_hex_ewkb(), "0106000020E610000002000000010300000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000010300000001000000050000000000000000002440000000000000244000000000000000C0000000000000244000000000000000C000000000000000C0000000000000244000000000000000C000000000000024400000000000002440");
198}
199
200#[test]
201#[rustfmt::skip]
202fn test_ewkb_adapters() {
203 let point = Point::new(10.0, -20.0, Some(4326));
204 let ewkb = EwkbPoint { geom: &point, srid: Some(4326), point_type: PointType::Point };
205 assert_eq!(ewkb.to_hex_ewkb(), "0101000020E6100000000000000000244000000000000034C0");
206 assert_eq!(point.as_ewkb().to_hex_ewkb(), "0101000020E6100000000000000000244000000000000034C0");
207}
208
209#[cfg(test)]
210#[rustfmt::skip]
211fn hex_to_vec(hexstr: &str) -> Vec<u8> {
212 hexstr.as_bytes().chunks(2).map(|chars| {
213 let hb = if chars[0] <= 57 { chars[0] - 48 } else { chars[0] - 55 };
214 let lb = if chars[1] <= 57 { chars[1] - 48 } else { chars[1] - 55 };
215 hb * 16 + lb
216 }).collect::<Vec<_>>()
217}
218
219#[test]
220#[rustfmt::skip]
221fn test_point_read() {
222 let ewkb = hex_to_vec("0101000000000000000000244000000000000034C0");
224 assert_eq!(ewkb, &[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 64, 0, 0, 0, 0, 0, 0, 52, 192]);
225 let point = Point::read_ewkb(&mut ewkb.as_slice()).unwrap();
226 assert_eq!(point.x(), 10.0);
227 assert_eq!(point.y(), -20.0);
228 assert_eq!(point.srid, None);
229
230 let ewkb = hex_to_vec("0101000080000000000000244000000000000034C00000000000005940");
232 let point = PointZ::read_ewkb(&mut ewkb.as_slice()).unwrap();
233 assert_eq!(point, PointZ { x: 10.0, y: -20.0, z: 100.0, srid: None });
234
235 let point = Point::read_ewkb(&mut ewkb.as_slice()).unwrap();
236 assert_eq!(point.x(), 10.0);
237 assert_eq!(point.y(), -20.0);
238 assert_eq!(point.srid, None);
239
240 let ewkb = hex_to_vec("0101000040000000000000244000000000000034C0000000000000F03F");
242 let point = PointM::read_ewkb(&mut ewkb.as_slice()).unwrap();
243 assert_eq!(point, PointM { x: 10.0, y: -20.0, m: 1.0, srid: None });
244
245 let ewkb = hex_to_vec("01010000C0000000000000244000000000000034C00000000000005940000000000000F03F");
247 let point = PointZM::read_ewkb(&mut ewkb.as_slice()).unwrap();
248 assert_eq!(point, PointZM { x: 10.0, y: -20.0, z: 100.0, m: 1.0, srid: None });
249}
250
251#[test]
252#[rustfmt::skip]
253fn test_line_read() {
254 let p = |x, y| Point::new(x, y, None);
255 let ewkb = hex_to_vec("010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF");
257 let line = LineStringT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
258 assert_eq!(line, LineStringT::<Point> {srid: None, points: vec![p(10.0, -20.0), p(0., -0.5)]});
259
260 let p = |x, y, z| PointZ { x, y, z, srid: Some(4326) };
261 let ewkb = hex_to_vec("01020000A0E610000002000000000000000000244000000000000034C000000000000059400000000000000000000000000000E0BF0000000000405940");
263 let line = LineStringT::<PointZ>::read_ewkb(&mut ewkb.as_slice()).unwrap();
264 assert_eq!(line, LineStringT::<PointZ> {srid: Some(4326), points: vec![p(10.0, -20.0, 100.0), p(0., -0.5, 101.0)]});
265}
266
267#[test]
268#[rustfmt::skip]
269fn test_polygon_read() {
270 let p = |x, y| Point::new(x, y, Some(4326));
271 let ewkb = hex_to_vec("0103000020E610000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000");
273 let poly = PolygonT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
274 let line = LineStringT::<Point> {srid: Some(4326), points: vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]};
275 assert_eq!(poly, PolygonT::<Point> {srid: Some(4326), rings: vec![line]});
276}
277
278#[test]
279#[rustfmt::skip]
280fn test_multipoint_read() {
281 let p = |x, y, z| PointZ { x, y, z, srid: None }; let ewkb = hex_to_vec("01040000A0E6100000020000000101000080000000000000244000000000000034C0000000000000594001010000800000000000000000000000000000E0BF0000000000405940");
284 let points = MultiPointT::<PointZ>::read_ewkb(&mut ewkb.as_slice()).unwrap();
285 assert_eq!(points, MultiPointT::<PointZ> {srid: Some(4326), points: vec![p(10.0, -20.0, 100.0), p(0., -0.5, 101.0)]});
286}
287
288#[test]
289#[rustfmt::skip]
290fn test_multiline_read() {
291 let p = |x, y| Point::new(x, y, None); let ewkb = hex_to_vec("0105000020E610000002000000010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF0102000000020000000000000000000000000000000000000000000000000000400000000000000000");
294 let poly = MultiLineStringT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
295 let line1 = LineStringT::<Point> {srid: None, points: vec![p(10.0, -20.0), p(0., -0.5)]};
296 let line2 = LineStringT::<Point> {srid: None, points: vec![p(0., 0.), p(2., 0.)]};
297 assert_eq!(poly, MultiLineStringT::<Point> {srid: Some(4326), lines: vec![line1, line2]});
298}
299
300#[test]
301#[rustfmt::skip]
302fn test_multipolygon_read() {
303 let p = |x, y| Point::new(x, y, None); let ewkb = hex_to_vec("0106000020E610000002000000010300000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000010300000001000000050000000000000000002440000000000000244000000000000000C0000000000000244000000000000000C000000000000000C0000000000000244000000000000000C000000000000024400000000000002440");
306 let multipoly = MultiPolygonT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
307 let line = LineStringT::<Point> {srid: None, points: vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]};
308 let poly1 = PolygonT::<Point> {srid: None, rings: vec![line]};
309 let line = LineStringT::<Point> {srid: None, points: vec![p(10., 10.), p(-2., 10.), p(-2., -2.), p(10., -2.), p(10., 10.)]};
310 let poly2 = PolygonT::<Point> {srid: None, rings: vec![line]};
311 assert_eq!(multipoly, MultiPolygonT::<Point> {srid: Some(4326), polygons: vec![poly1, poly2]});
312}
313
314#[test]
315#[rustfmt::skip]
316fn test_geometrycollection_read() {
317 let ewkb = hex_to_vec("01070000000300000001010000000000000000002440000000000000244001010000000000000000003E400000000000003E400102000000020000000000000000002E400000000000002E4000000000000034400000000000003440");
319 let geom = GeometryCollectionT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
320
321 assert_eq!(geom.geometries.len(), 3);
323 assert_eq!(geom.srid, None);
324
325 match &geom.geometries[0] {
327 GeometryT::Point(pt) => {
328 assert_eq!(pt.x(), 10.0);
329 assert_eq!(pt.y(), 10.0);
330 assert_eq!(pt.srid, None);
331 },
332 _ => panic!("First geometry is not a Point")
333 }
334
335 match &geom.geometries[1] {
337 GeometryT::Point(pt) => {
338 assert_eq!(pt.x(), 30.0);
339 assert_eq!(pt.y(), 30.0);
340 assert_eq!(pt.srid, None);
341 },
342 _ => panic!("Second geometry is not a Point")
343 }
344
345 match &geom.geometries[2] {
347 GeometryT::LineString(ls) => {
348 assert_eq!(ls.points.len(), 2);
349 assert_eq!(ls.points[0].x(), 15.0);
350 assert_eq!(ls.points[0].y(), 15.0);
351 assert_eq!(ls.points[1].x(), 20.0);
352 assert_eq!(ls.points[1].y(), 20.0);
353 },
354 _ => panic!("Third geometry is not a LineString")
355 }
356}
357
358#[test]
359#[rustfmt::skip]
360fn test_geometry_read() {
361 let ewkb = hex_to_vec("01010000C0000000000000244000000000000034C00000000000005940000000000000F03F");
363 let geom = GeometryT::<PointZM>::read_ewkb(&mut ewkb.as_slice()).unwrap();
364 assert_eq!(format!("{:.0?}", geom), "Point(PointZM { x: 10, y: -20, z: 100, m: 1, srid: None })");
365 let ewkb = hex_to_vec("01020000A0E610000002000000000000000000244000000000000034C000000000000059400000000000000000000000000000E0BF0000000000405940");
367 let geom = GeometryT::<PointZ>::read_ewkb(&mut ewkb.as_slice()).unwrap();
368 assert_eq!(format!("{:.1?}", geom), "LineString(LineStringT { points: [PointZ { x: 10.0, y: -20.0, z: 100.0, srid: Some(4326) }, PointZ { x: 0.0, y: -0.5, z: 101.0, srid: Some(4326) }], srid: Some(4326) })");
369 let ewkb = hex_to_vec("0103000020E610000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000");
371 let geom = GeometryT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
372
373 match &geom {
375 GeometryT::Polygon(poly) => {
376 assert_eq!(poly.srid, Some(4326));
377 assert_eq!(poly.rings.len(), 1);
378
379 let ring = &poly.rings[0];
381 assert_eq!(ring.points.len(), 5);
382
383 let expected_points = [
385 (0.0, 0.0),
386 (2.0, 0.0),
387 (2.0, 2.0),
388 (0.0, 2.0),
389 (0.0, 0.0)
390 ];
391
392 for (i, point) in ring.points.iter().enumerate() {
394 assert_eq!(point.x(), expected_points[i].0);
395 assert_eq!(point.y(), expected_points[i].1);
396 assert_eq!(point.srid, Some(4326));
397 }
398 },
399 _ => panic!("Geometry is not a Polygon")
400 }
401 let ewkb = hex_to_vec("01040000A0E6100000020000000101000080000000000000244000000000000034C0000000000000594001010000800000000000000000000000000000E0BF0000000000405940");
403 let geom = GeometryT::<PointZ>::read_ewkb(&mut ewkb.as_slice()).unwrap();
404 assert_eq!(format!("{:.1?}", geom), "MultiPoint(MultiPointT { points: [PointZ { x: 10.0, y: -20.0, z: 100.0, srid: None }, PointZ { x: 0.0, y: -0.5, z: 101.0, srid: None }], srid: Some(4326) })");
405 let ewkb = hex_to_vec("0105000020E610000002000000010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF0102000000020000000000000000000000000000000000000000000000000000400000000000000000");
407 let geom = GeometryT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
408
409 match &geom {
411 GeometryT::MultiLineString(mls) => {
412 assert_eq!(mls.srid, Some(4326));
413 assert_eq!(mls.lines.len(), 2);
414
415 let line1 = &mls.lines[0];
417 assert_eq!(line1.points.len(), 2);
418 assert_eq!(line1.points[0].x(), 10.0);
419 assert_eq!(line1.points[0].y(), -20.0);
420 assert_eq!(line1.points[1].x(), 0.0);
421 assert_eq!(line1.points[1].y(), -0.5);
422
423 let line2 = &mls.lines[1];
425 assert_eq!(line2.points.len(), 2);
426 assert_eq!(line2.points[0].x(), 0.0);
427 assert_eq!(line2.points[0].y(), 0.0);
428 assert_eq!(line2.points[1].x(), 2.0);
429 assert_eq!(line2.points[1].y(), 0.0);
430 },
431 _ => panic!("Geometry is not a MultiLineString")
432 };
433 let ewkb = hex_to_vec("0106000020E610000002000000010300000001000000050000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000000000000000000000010300000001000000050000000000000000002440000000000000244000000000000000C0000000000000244000000000000000C000000000000000C0000000000000244000000000000000C000000000000024400000000000002440");
435 let geom = GeometryT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
436
437 match &geom {
439 GeometryT::MultiPolygon(mpoly) => {
440 assert_eq!(mpoly.srid, Some(4326));
441 assert_eq!(mpoly.polygons.len(), 2);
442
443 let poly1 = &mpoly.polygons[0];
445 assert_eq!(poly1.rings.len(), 1);
446 let ring1 = &poly1.rings[0];
447 assert_eq!(ring1.points.len(), 5);
448
449 let points1 = [
451 (0.0, 0.0),
452 (2.0, 0.0),
453 (2.0, 2.0),
454 (0.0, 2.0),
455 (0.0, 0.0)
456 ];
457
458 for (i, pt) in ring1.points.iter().enumerate() {
459 assert_eq!(pt.x(), points1[i].0);
460 assert_eq!(pt.y(), points1[i].1);
461 }
462
463 let poly2 = &mpoly.polygons[1];
465 assert_eq!(poly2.rings.len(), 1);
466 let ring2 = &poly2.rings[0];
467 assert_eq!(ring2.points.len(), 5);
468
469 let points2 = [
471 (10.0, 10.0),
472 (-2.0, 10.0),
473 (-2.0, -2.0),
474 (10.0, -2.0),
475 (10.0, 10.0)
476 ];
477
478 for (i, pt) in ring2.points.iter().enumerate() {
479 assert_eq!(pt.x(), points2[i].0);
480 assert_eq!(pt.y(), points2[i].1);
481 }
482 },
483 _ => panic!("Geometry is not a MultiPolygon")
484 };
485 let ewkb = hex_to_vec("01070000000300000001010000000000000000002440000000000000244001010000000000000000003E400000000000003E400102000000020000000000000000002E400000000000002E4000000000000034400000000000003440");
487 let geom = GeometryT::<Point>::read_ewkb(&mut ewkb.as_slice()).unwrap();
488
489 match &geom {
491 GeometryT::GeometryCollection(gc) => {
492 assert_eq!(gc.srid, None);
493 assert_eq!(gc.geometries.len(), 3);
494
495 match &gc.geometries[0] {
497 GeometryT::Point(pt) => {
498 assert_eq!(pt.x(), 10.0);
499 assert_eq!(pt.y(), 10.0);
500 },
501 _ => panic!("First geometry is not a Point")
502 }
503
504 match &gc.geometries[1] {
506 GeometryT::Point(pt) => {
507 assert_eq!(pt.x(), 30.0);
508 assert_eq!(pt.y(), 30.0);
509 },
510 _ => panic!("Second geometry is not a Point")
511 }
512
513 match &gc.geometries[2] {
515 GeometryT::LineString(ls) => {
516 assert_eq!(ls.points.len(), 2);
517 assert_eq!(ls.points[0].x(), 15.0);
518 assert_eq!(ls.points[0].y(), 15.0);
519 assert_eq!(ls.points[1].x(), 20.0);
520 assert_eq!(ls.points[1].y(), 20.0);
521 },
522 _ => panic!("Third geometry is not a LineString")
523 }
524 },
525 _ => panic!("Geometry is not a GeometryCollection")
526 };
527}
528
529#[test]
530#[rustfmt::skip]
531fn test_read_error() {
532 let ewkb = hex_to_vec("010200000002000000000000000000244000000000000034C00000000000000000000000000000E0BF");
534 let poly = PolygonT::<Point>::read_ewkb(&mut ewkb.as_slice());
535 assert!(poly.is_err()); }
537
538#[test]
539#[rustfmt::skip]
540fn test_iterators() {
541 use crate::types::LineString;
543
544 let p = |x, y| Point::new(x, y, None);
545 let line = self::LineStringT::<Point> {srid: Some(4326), points: vec![p(10.0, -20.0), p(0., -0.5)]};
546 let last_point = line.points().last().unwrap();
547 assert_eq!(last_point.x(), 0.);
548 assert_eq!(last_point.y(), -0.5);
549 assert_eq!(last_point.srid, None);
550}
551
552#[cfg(all(test, feature = "serde"))]
553mod serde_tests {
554 use super::*;
555 use serde_json;
556
557 #[test]
558 fn test_serde_point() {
559 let point = Point::new(10.0, 20.0, Some(4326));
560
561 let serialized = serde_json::to_string(&point).unwrap();
562 let deserialized: Point = serde_json::from_str(&serialized).unwrap();
563
564 assert_eq!(point, deserialized);
565 }
566
567 #[test]
568 fn test_serde_point_z() {
569 let point = PointZ {
570 x: 10.0,
571 y: 20.0,
572 z: 30.0,
573 srid: Some(4326),
574 };
575
576 let serialized = serde_json::to_string(&point).unwrap();
577 let deserialized: PointZ = serde_json::from_str(&serialized).unwrap();
578
579 assert_eq!(point, deserialized);
580 }
581
582 #[test]
583 fn test_serde_geometry_t() {
584 let point = Point::new(10.0, 20.0, Some(4326));
585 let geometry = GeometryT::Point(point);
586
587 let serialized = serde_json::to_string(&geometry).unwrap();
588 let deserialized: GeometryT<Point> = serde_json::from_str(&serialized).unwrap();
589
590 match deserialized {
591 GeometryT::Point(p) => assert_eq!(p, point),
592 _ => panic!("Deserialized to wrong variant"),
593 }
594 }
595}