diff --git a/CHANGES.md b/CHANGES.md index 58d20a7..3f23d74 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,9 @@ # Changes ## UNRELEASED - +* add support for serializing integer geometries, so you can now: + `geo_types::Point::new(1i32, 2i32).wkt_string()` + Note that deserializing integer geometries is not yet supported. * docs.rs documentation now shows all optional features. * * docs.rs documentation items are annotated with their feature requirements. diff --git a/src/geo_types_to_wkt.rs b/src/geo_types_to_wkt.rs index 456c643..a97f6f4 100644 --- a/src/geo_types_to_wkt.rs +++ b/src/geo_types_to_wkt.rs @@ -1,4 +1,4 @@ -use geo_types::CoordFloat; +use geo_types::CoordNum; use crate::types::{ Coord, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, @@ -17,7 +17,7 @@ use crate::{Geometry, ToWkt, Wkt}; /// ``` impl ToWkt for geo_types::Geometry where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { match self { @@ -46,7 +46,7 @@ where /// ``` impl ToWkt for geo_types::Point where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -66,7 +66,7 @@ where /// ``` impl ToWkt for geo_types::Line where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -86,7 +86,7 @@ where /// ``` impl ToWkt for geo_types::LineString where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -106,7 +106,7 @@ where /// ``` impl ToWkt for geo_types::Polygon where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -126,7 +126,7 @@ where /// ``` impl ToWkt for geo_types::MultiPoint where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -148,7 +148,7 @@ where /// ``` impl ToWkt for geo_types::MultiLineString where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -172,7 +172,7 @@ where /// ``` impl ToWkt for geo_types::MultiPolygon where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -194,7 +194,7 @@ where /// ``` impl ToWkt for geo_types::GeometryCollection where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -214,7 +214,7 @@ where /// ``` impl ToWkt for geo_types::Rect where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -234,7 +234,7 @@ where /// ``` impl ToWkt for geo_types::Triangle where - T: CoordFloat + std::fmt::Display, + T: CoordNum + std::fmt::Display, { fn to_wkt(&self) -> Wkt { Wkt { @@ -245,7 +245,7 @@ where fn g_point_to_w_coord(g_point: &geo_types::Coordinate) -> Coord where - T: CoordFloat, + T: CoordNum, { Coord { x: g_point.x, @@ -257,7 +257,7 @@ where fn g_point_to_w_point(g_point: &geo_types::Point) -> Point where - T: CoordFloat, + T: CoordNum, { let coord = g_point_to_w_coord(&g_point.0); Point(Some(coord)) @@ -265,14 +265,14 @@ where fn g_points_to_w_coords(g_points: &[geo_types::Coordinate]) -> Vec> where - T: CoordFloat, + T: CoordNum, { g_points.iter().map(g_point_to_w_coord).collect() } fn g_points_to_w_points(g_points: &[geo_types::Point]) -> Vec> where - T: CoordFloat, + T: CoordNum, { g_points .iter() @@ -284,14 +284,14 @@ where fn g_line_to_w_linestring(g_line: &geo_types::Line) -> LineString where - T: CoordFloat, + T: CoordNum, { g_points_to_w_linestring(&[g_line.start, g_line.end]) } fn g_linestring_to_w_linestring(g_linestring: &geo_types::LineString) -> LineString where - T: CoordFloat, + T: CoordNum, { let &geo_types::LineString(ref g_points) = g_linestring; g_points_to_w_linestring(g_points) @@ -299,7 +299,7 @@ where fn g_points_to_w_linestring(g_coords: &[geo_types::Coordinate]) -> LineString where - T: CoordFloat, + T: CoordNum, { let w_coords = g_points_to_w_coords(g_coords); LineString(w_coords) @@ -307,7 +307,7 @@ where fn g_lines_to_w_lines(g_lines: &[geo_types::LineString]) -> Vec> where - T: CoordFloat, + T: CoordNum, { let mut w_lines = vec![]; for g_line in g_lines { @@ -319,7 +319,7 @@ where fn g_triangle_to_w_polygon(g_triangle: &geo_types::Triangle) -> Polygon where - T: CoordFloat, + T: CoordNum, { let polygon = g_triangle.to_polygon(); g_polygon_to_w_polygon(&polygon) @@ -327,7 +327,7 @@ where fn g_rect_to_w_polygon(g_rect: &geo_types::Rect) -> Polygon where - T: CoordFloat, + T: CoordNum, { let polygon = g_rect.to_polygon(); g_polygon_to_w_polygon(&polygon) @@ -335,7 +335,7 @@ where fn g_polygon_to_w_polygon(g_polygon: &geo_types::Polygon) -> Polygon where - T: CoordFloat, + T: CoordNum, { let outer_line = g_polygon.exterior(); let inner_lines = g_polygon.interiors(); @@ -356,7 +356,7 @@ where fn g_mpoint_to_w_mpoint(g_mpoint: &geo_types::MultiPoint) -> MultiPoint where - T: CoordFloat, + T: CoordNum, { let &geo_types::MultiPoint(ref g_points) = g_mpoint; let w_points = g_points_to_w_points(g_points); @@ -365,7 +365,7 @@ where fn g_mline_to_w_mline(g_mline: &geo_types::MultiLineString) -> MultiLineString where - T: CoordFloat, + T: CoordNum, { let &geo_types::MultiLineString(ref g_lines) = g_mline; let w_lines = g_lines_to_w_lines(g_lines); @@ -374,7 +374,7 @@ where fn g_polygons_to_w_polygons(g_polygons: &[geo_types::Polygon]) -> Vec> where - T: CoordFloat, + T: CoordNum, { let mut w_polygons = vec![]; for g_polygon in g_polygons { @@ -385,7 +385,7 @@ where fn g_mpolygon_to_w_mpolygon(g_mpolygon: &geo_types::MultiPolygon) -> MultiPolygon where - T: CoordFloat, + T: CoordNum, { let &geo_types::MultiPolygon(ref g_polygons) = g_mpolygon; let w_polygons = g_polygons_to_w_polygons(g_polygons); @@ -394,7 +394,7 @@ where fn g_geocol_to_w_geocol(g_geocol: &geo_types::GeometryCollection) -> GeometryCollection where - T: CoordFloat, + T: CoordNum, { let &geo_types::GeometryCollection(ref g_geoms) = g_geocol; let mut w_geoms = vec![]; @@ -407,7 +407,7 @@ where fn g_geom_to_w_geom(g_geom: &geo_types::Geometry) -> Geometry where - T: CoordFloat, + T: CoordNum, { match *g_geom { geo_types::Geometry::Point(ref g_point) => g_point_to_w_point(g_point).as_item(), @@ -439,3 +439,23 @@ where } } } + +#[cfg(test)] +mod tests { + use crate::ToWkt; + + #[test] + fn integer_geom() { + let point = geo_types::Point::new(1i32, 2i32); + assert_eq!("POINT(1 2)", &point.wkt_string()); + } + + #[test] + fn float_geom() { + let point = geo_types::Point::new(1f32, 2f32); + assert_eq!("POINT(1 2)", &point.wkt_string()); + + let point = geo_types::Point::new(1.1f32, 2.9f32); + assert_eq!("POINT(1.1 2.9)", &point.wkt_string()); + } +} diff --git a/src/lib.rs b/src/lib.rs index 9edd339..64fea99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,14 +121,19 @@ pub use from_wkt::TryFromWkt; #[cfg(all(feature = "serde", feature = "geo-types"))] pub use deserialize::{deserialize_geometry, deserialize_point}; -pub trait WktFloat: num_traits::Float + std::fmt::Debug {} -impl WktFloat for T where T: num_traits::Float + std::fmt::Debug {} +use num_traits::{Float, Num, NumCast}; + +pub trait WktNum: Num + NumCast + Copy + fmt::Debug {} +impl WktNum for T where T: Num + NumCast + Copy + fmt::Debug {} + +pub trait WktFloat: WktNum + Float {} +impl WktFloat for T where T: WktNum + Float {} #[derive(Clone, Debug)] /// All supported WKT geometry [`types`] pub enum Geometry where - T: WktFloat, + T: WktNum, { Point(Point), LineString(LineString), @@ -183,7 +188,7 @@ where impl fmt::Display for Geometry where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self { @@ -204,7 +209,7 @@ where /// This type can be fallibly converted to a [`geo_types`] primitive using [`std::convert::TryFrom`]. pub struct Wkt where - T: WktFloat, + T: WktNum, { pub item: Geometry, } @@ -244,7 +249,7 @@ where impl fmt::Display for Wkt where - T: WktFloat + fmt::Debug + fmt::Display, + T: WktNum + fmt::Debug + fmt::Display, { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.item.fmt(formatter) diff --git a/src/to_wkt.rs b/src/to_wkt.rs index be6c8b3..8219d5c 100644 --- a/src/to_wkt.rs +++ b/src/to_wkt.rs @@ -1,9 +1,9 @@ -use crate::{Wkt, WktFloat}; +use crate::{Wkt, WktNum}; /// A trait for converting values to WKT pub trait ToWkt where - T: WktFloat + std::fmt::Display, + T: WktNum + std::fmt::Display, { /// Converts the value of `self` to an [`Wkt`] struct. /// diff --git a/src/types/coord.rs b/src/types/coord.rs index 547823e..5497e52 100644 --- a/src/types/coord.rs +++ b/src/types/coord.rs @@ -13,14 +13,14 @@ // limitations under the License. use crate::tokenizer::{PeekableTokens, Token}; -use crate::{FromTokens, WktFloat}; +use crate::{FromTokens, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] pub struct Coord where - T: WktFloat, + T: WktNum, { pub x: T, pub y: T, @@ -30,7 +30,7 @@ where impl fmt::Display for Coord where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{} {}", self.x, self.y)?; diff --git a/src/types/geometrycollection.rs b/src/types/geometrycollection.rs index 7e2a015..fb985b0 100644 --- a/src/types/geometrycollection.rs +++ b/src/types/geometrycollection.rs @@ -13,16 +13,16 @@ // limitations under the License. use crate::tokenizer::{PeekableTokens, Token}; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct GeometryCollection(pub Vec>); +pub struct GeometryCollection(pub Vec>); impl GeometryCollection where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::GeometryCollection(self) @@ -31,7 +31,7 @@ where impl fmt::Display for GeometryCollection where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() { diff --git a/src/types/linestring.rs b/src/types/linestring.rs index 07e8e17..005d53d 100644 --- a/src/types/linestring.rs +++ b/src/types/linestring.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::coord::Coord; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct LineString(pub Vec>); +pub struct LineString(pub Vec>); impl LineString where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::LineString(self) @@ -42,7 +42,7 @@ where impl fmt::Display for LineString where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() { diff --git a/src/types/multilinestring.rs b/src/types/multilinestring.rs index 23de4ae..8a4d6fd 100644 --- a/src/types/multilinestring.rs +++ b/src/types/multilinestring.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::linestring::LineString; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct MultiLineString(pub Vec>); +pub struct MultiLineString(pub Vec>); impl MultiLineString where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::MultiLineString(self) @@ -32,7 +32,7 @@ where impl fmt::Display for MultiLineString where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() { diff --git a/src/types/multipoint.rs b/src/types/multipoint.rs index f02f594..e36c8e4 100644 --- a/src/types/multipoint.rs +++ b/src/types/multipoint.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::point::Point; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct MultiPoint(pub Vec>); +pub struct MultiPoint(pub Vec>); impl MultiPoint where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::MultiPoint(self) @@ -32,7 +32,7 @@ where impl fmt::Display for MultiPoint where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() { diff --git a/src/types/multipolygon.rs b/src/types/multipolygon.rs index 6e6700e..e9a9b24 100644 --- a/src/types/multipolygon.rs +++ b/src/types/multipolygon.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::polygon::Polygon; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct MultiPolygon(pub Vec>); +pub struct MultiPolygon(pub Vec>); impl MultiPolygon where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::MultiPolygon(self) @@ -32,7 +32,7 @@ where impl fmt::Display for MultiPolygon where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() { diff --git a/src/types/point.rs b/src/types/point.rs index fb5a95c..95ed51f 100644 --- a/src/types/point.rs +++ b/src/types/point.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::coord::Coord; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct Point(pub Option>); +pub struct Point(pub Option>); impl Point where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::Point(self) @@ -32,7 +32,7 @@ where impl fmt::Display for Point where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self.0 { diff --git a/src/types/polygon.rs b/src/types/polygon.rs index 1acea06..b7e53e7 100644 --- a/src/types/polygon.rs +++ b/src/types/polygon.rs @@ -14,16 +14,16 @@ use crate::tokenizer::PeekableTokens; use crate::types::linestring::LineString; -use crate::{FromTokens, Geometry, WktFloat}; +use crate::{FromTokens, Geometry, WktFloat, WktNum}; use std::fmt; use std::str::FromStr; #[derive(Clone, Debug, Default)] -pub struct Polygon(pub Vec>); +pub struct Polygon(pub Vec>); impl Polygon where - T: WktFloat, + T: WktNum, { pub fn as_item(self) -> Geometry { Geometry::Polygon(self) @@ -32,7 +32,7 @@ where impl fmt::Display for Polygon where - T: WktFloat + fmt::Display, + T: WktNum + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.0.is_empty() {