diff --git a/examples/from_geo.rs b/examples/from_geo.rs index 69cf820..33afe3e 100644 --- a/examples/from_geo.rs +++ b/examples/from_geo.rs @@ -5,9 +5,9 @@ extern crate geos; #[cfg(feature = "geo")] use geo_types::{Coordinate, LineString, Polygon}; #[cfg(feature = "geo")] -use geos::from_geo::TryInto; -#[cfg(feature = "geo")] use geos::{Error, Geom, Geometry}; +#[cfg(feature = "geo")] +use std::convert::TryInto; #[cfg(feature = "geo")] fn fun() -> Result<(), Error> { @@ -33,10 +33,11 @@ fn fun() -> Result<(), Error> { let geom: Geometry = (&p).try_into()?; assert!(geom.contains(&geom)?); - assert!(!geom.contains(&(&exterior).try_into()?)?); + let tmp: Geometry = (&exterior).try_into()?; + assert!(!geom.contains(&tmp)?); - assert!(geom.covers(&(&exterior).try_into()?)?); - assert!(geom.touches(&(&exterior).try_into()?)?); + assert!(geom.covers(&tmp)?); + assert!(geom.touches(&tmp)?); Ok(()) } diff --git a/src/from_geo.rs b/src/from_geo.rs index b9a5d2e..29762c3 100644 --- a/src/from_geo.rs +++ b/src/from_geo.rs @@ -1,14 +1,10 @@ use crate::{CoordDimensions, CoordSeq, Geometry as GGeometry}; use error::Error; use geo_types::{Coordinate, LineString, MultiPolygon, Point, Polygon}; + use std; use std::borrow::Borrow; - -// define our own TryInto while the std trait is not stable -pub trait TryInto { - type Err; - fn try_into(self) -> Result; -} +use std::convert::{TryFrom, TryInto}; fn create_coord_seq_from_vec<'a>(coords: &'a [Coordinate]) -> Result { create_coord_seq(coords.iter(), coords.len()) @@ -27,21 +23,21 @@ where Ok(coord_seq) } -impl<'a> TryInto> for &'a Point { - type Err = Error; +impl<'a> TryFrom<&'a Point> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let coord_seq = create_coord_seq(std::iter::once(&self.0), 1)?; + fn try_from(other: &'a Point) -> Result, Self::Error> { + let coord_seq = create_coord_seq(std::iter::once(&other.0), 1)?; GGeometry::create_point(coord_seq) } } -impl<'a, T: Borrow>> TryInto> for &'a [T] { - type Err = Error; +impl<'a, T: Borrow>> TryFrom<&'a [T]> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let geom_points = self + fn try_from(other: &'a [T]) -> Result, Self::Error> { + let geom_points = other .into_iter() .map(|p| p.borrow().try_into()) .collect::, _>>()?; @@ -50,11 +46,11 @@ impl<'a, T: Borrow>> TryInto> for &'a [T] { } } -impl<'a> TryInto> for &'a LineString { - type Err = Error; +impl<'a> TryFrom<&'a LineString> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let coord_seq = create_coord_seq_from_vec(self.0.as_slice())?; + fn try_from(other: &'a LineString) -> Result, Self::Error> { + let coord_seq = create_coord_seq_from_vec(other.0.as_slice())?; GGeometry::create_line_string(coord_seq) } @@ -66,11 +62,11 @@ struct LineRing<'a>(&'a LineString); /// Convert a geo_types::LineString to a geos LinearRing /// a LinearRing should be closed so cloase the geometry if needed -impl<'a, 'b> TryInto> for &'a LineRing<'b> { - type Err = Error; +impl<'a> TryFrom> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let points = &(self.0).0; + fn try_from(other: LineRing<'a>) -> Result, Self::Error> { + let points = &(other.0).0; let nb_points = points.len(); if nb_points > 0 && nb_points < 3 { return Err(Error::InvalidGeometry( @@ -95,14 +91,14 @@ impl<'a, 'b> TryInto> for &'a LineRing<'b> { } } -impl<'a> TryInto> for &'a Polygon { - type Err = Error; +impl<'a> TryFrom<&'a Polygon> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let ring = LineRing(self.exterior()); + fn try_from(other: &'a Polygon) -> Result, Self::Error> { + let ring = LineRing(other.exterior()); let geom_exterior: GGeometry = ring.try_into()?; - let interiors: Vec<_> = self + let interiors: Vec<_> = other .interiors() .iter() .map(|i| LineRing(i).try_into()) @@ -112,11 +108,11 @@ impl<'a> TryInto> for &'a Polygon { } } -impl<'a> TryInto> for &'a MultiPolygon { - type Err = Error; +impl<'a> TryFrom<&'a MultiPolygon> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - let polygons: Vec<_> = self + fn try_from(other: &'a MultiPolygon) -> Result, Self::Error> { + let polygons: Vec<_> = other .0 .iter() .map(|p| p.try_into()) @@ -130,8 +126,8 @@ impl<'a> TryInto> for &'a MultiPolygon { mod test { use super::LineRing; use crate::{Geom, Geometry as GGeometry}; - use from_geo::TryInto; use geo_types::{Coordinate, LineString, MultiPolygon, Polygon}; + use std::convert::TryInto; fn coords(tuples: Vec<(f64, f64)>) -> Vec> { tuples.into_iter().map(Coordinate::from).collect() @@ -161,10 +157,12 @@ mod test { let geom: GGeometry = (&p).try_into().unwrap(); assert!(geom.contains(&geom).unwrap()); - assert!(!geom.contains(&(&exterior).try_into().unwrap()).unwrap()); - assert!(geom.covers(&(&exterior).try_into().unwrap()).unwrap()); - assert!(geom.touches(&(&exterior).try_into().unwrap()).unwrap()); + let tmp: GGeometry = (&exterior).try_into().unwrap(); + + assert!(!geom.contains(&tmp).unwrap()); + assert!(geom.covers(&tmp).unwrap()); + assert!(geom.touches(&tmp).unwrap()); } #[test] @@ -189,7 +187,7 @@ mod test { let geom: GGeometry = (&mp).try_into().unwrap(); assert!(geom.contains(&geom).unwrap()); - assert!(geom.contains(&(&p).try_into().unwrap()).unwrap()); + assert!(geom.contains::(&(&p).try_into().unwrap()).unwrap()); } #[test] @@ -199,7 +197,7 @@ mod test { let p = Polygon::new(exterior, interiors); let mp = MultiPolygon(vec![p.clone()]); - let geom = (&mp).try_into(); + let geom: Result = (&mp).try_into(); assert!(geom.is_err()); } @@ -224,7 +222,7 @@ mod test { let p = Polygon::new(exterior, interiors); let mp = MultiPolygon(vec![p]); - let _g = (&mp).try_into().unwrap(); // no error + let _g: GGeometry = (&mp).try_into().unwrap(); // no error } /// a linear ring can be empty diff --git a/src/from_geojson.rs b/src/from_geojson.rs index eda2bdc..3ae91e5 100644 --- a/src/from_geojson.rs +++ b/src/from_geojson.rs @@ -1,12 +1,9 @@ use crate::{CoordDimensions, CoordSeq, Geometry as GGeometry}; use error::{Error, GResult}; use geojson::{Geometry, Value}; -use std::iter; -pub trait TryInto { - type Err; - fn try_into(self) -> Result; -} +use std::convert::{TryFrom, TryInto}; +use std::iter; fn create_coord_seq_from_vec<'a>(coords: &'a [Vec]) -> Result { create_coord_seq(coords.iter(), coords.len()) @@ -42,11 +39,11 @@ fn create_closed_coord_seq_from_vec<'a>(points: &'a [Vec]) -> Result TryInto> for &'a Geometry { - type Err = Error; +impl<'a> TryFrom<&'a Geometry> for GGeometry<'a> { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { - match self.value { + fn try_from(other: &'a Geometry) -> Result, Self::Error> { + match other.value { Value::Point(ref c) => GGeometry::create_point(create_coord_seq(iter::once(c), 1)?), Value::MultiPoint(ref pts) => { let ggpts = pts @@ -108,7 +105,7 @@ impl<'a> TryInto> for &'a Geometry { Value::GeometryCollection(ref geoms) => { let _geoms = geoms .iter() - .map(|ref geom| geom.try_into()) + .map(|geom| geom.try_into()) .collect::>>()?; GGeometry::create_geometry_collection(_geoms) } @@ -118,14 +115,15 @@ impl<'a> TryInto> for &'a Geometry { #[cfg(test)] mod test { - use crate::from_geojson::TryInto; use crate::{Geom, Geometry as GGeometry}; use geojson::{Geometry, Value}; + use std::convert::TryInto; + #[test] fn geom_from_geojson_point() { let geojson_pt = Geometry::new(Value::Point(vec![1., 1.])); - let gpoint: GGeometry = geojson_pt.try_into().unwrap(); + let gpoint: GGeometry = (&geojson_pt).try_into().unwrap(); assert_eq!(gpoint.to_wkt_precision(0), Ok("POINT (1 1)".to_string()),); } @@ -133,7 +131,7 @@ mod test { #[test] fn geom_from_geojson_multipoint() { let geojson_pts = Geometry::new(Value::MultiPoint(vec![vec![1., 1.], vec![2., 2.]])); - let gpts: GGeometry = geojson_pts.try_into().unwrap(); + let gpts: GGeometry = (&geojson_pts).try_into().unwrap(); assert_eq!( gpts.to_wkt_precision(0), Ok("MULTIPOINT (1 1, 2 2)".to_string()), @@ -143,7 +141,7 @@ mod test { #[test] fn geom_from_geojson_line() { let geojson_line = Geometry::new(Value::LineString(vec![vec![1., 1.], vec![2., 2.]])); - let gline: GGeometry = geojson_line.try_into().unwrap(); + let gline: GGeometry = (&geojson_line).try_into().unwrap(); assert_eq!( gline.to_wkt_precision(0), Ok("LINESTRING (1 1, 2 2)".to_string()), @@ -156,7 +154,7 @@ mod test { vec![vec![1., 1.], vec![2., 2.]], vec![vec![3., 3.], vec![4., 4.]], ])); - let glines: GGeometry = geojson_lines.try_into().unwrap(); + let glines: GGeometry = (&geojson_lines).try_into().unwrap(); assert_eq!( glines.to_wkt_precision(0), Ok("MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))".to_string()), @@ -181,7 +179,7 @@ mod test { vec![0.2, 0.2], ], ])); - let gpolygon: GGeometry = geojson_polygon.try_into().unwrap(); + let gpolygon: GGeometry = (&geojson_polygon).try_into().unwrap(); assert_eq!( gpolygon.to_wkt_precision(1), Ok("POLYGON ((0.0 0.0, 0.0 3.0, 3.0 3.0, 3.0 0.0, 0.0 0.0), (0.2 0.2, 0.2 2.0, 2.0 2.0, 2.0 0.2, 0.2 0.2))" @@ -201,7 +199,7 @@ mod test { ], vec![vec![0.2, 0.2], vec![0.2, 2.], vec![2., 2.], vec![2., 0.2]], ])); - let gpolygon: GGeometry = geojson_polygon.try_into().unwrap(); + let gpolygon: GGeometry = (&geojson_polygon).try_into().unwrap(); assert_eq!( gpolygon.to_wkt_precision(1), Ok("POLYGON ((0.0 0.0, 0.0 3.0, 3.0 3.0, 3.0 0.0, 0.0 0.0), (0.2 0.2, 0.2 2.0, 2.0 2.0, 2.0 0.2, 0.2 0.2))" @@ -218,7 +216,7 @@ mod test { vec![1., 0.], vec![0., 0.], ]]])); - let gmultipolygon: GGeometry = geojson_multipolygon.try_into().unwrap(); + let gmultipolygon: GGeometry = (&geojson_multipolygon).try_into().unwrap(); assert_eq!( gmultipolygon.to_wkt_precision(0), Ok("MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0)))".to_string()), @@ -231,7 +229,7 @@ mod test { Geometry::new(Value::Point(vec![1., 1.])), Geometry::new(Value::LineString(vec![vec![1., 1.], vec![2., 2.]])), ])); - let gc: GGeometry = geojson_gc.try_into().unwrap(); + let gc: GGeometry = (&geojson_gc).try_into().unwrap(); assert_eq!( gc.to_wkt_precision(0), Ok("GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (1 1, 2 2))".to_string()), diff --git a/src/to_geo.rs b/src/to_geo.rs index 2c7f1c8..af21470 100644 --- a/src/to_geo.rs +++ b/src/to_geo.rs @@ -1,20 +1,21 @@ use crate::{ConstGeometry, Geom, Geometry as GGeometry}; use error::Error; -use from_geo::TryInto; use geo_types::Geometry; use wkt; use wkt::conversion::try_into_geometry; +use std::convert::TryFrom; + macro_rules! impl_try_into { ($ty_name:ident $(,$lt:lifetime)?) => ( -impl<'a$(,$lt)?> TryInto> for $ty_name<'a$(,$lt)?> { - type Err = Error; +impl<'a$(,$lt)?> TryFrom<$ty_name<'a$(,$lt)?>> for Geometry { + type Error = Error; - fn try_into(self) -> Result, Self::Err> { + fn try_from(other: $ty_name<'a$(,$lt)?>) -> Result, Self::Error> { // This is a first draft, it's very inefficient, we use wkt as a pivot format to // translate the geometry. // We should at least use wkb, or even better implement a direct translation - let wkt_str = self.to_wkt()?; + let wkt_str = other.to_wkt()?; let wkt_obj = wkt::Wkt::from_str(&wkt_str) .map_err(|e| Error::ConversionError(format!("impossible to read wkt: {}", e)))?; @@ -37,8 +38,8 @@ impl_try_into!(ConstGeometry, 'c); #[cfg(test)] mod test { use crate::Geometry as GGeometry; - use from_geo::TryInto; use geo_types::{Coordinate, Geometry, LineString, MultiPolygon, Polygon}; + use std::convert::TryInto; fn coords(tuples: Vec<(f64, f64)>) -> Vec> { tuples.into_iter().map(Coordinate::from).collect() diff --git a/src/to_geojson.rs b/src/to_geojson.rs index 1ae2982..429e1a3 100644 --- a/src/to_geojson.rs +++ b/src/to_geojson.rs @@ -2,10 +2,7 @@ use crate::{ConstGeometry, CoordSeq, Geom, Geometry as GGeometry, GeometryTypes} use error::{Error, GResult}; use geojson::{Geometry, Value}; -pub trait TryInto { - type Err; - fn try_into(self) -> Result; -} +use std::convert::{TryFrom, TryInto}; fn coords_seq_to_vec_position(cs: &CoordSeq) -> GResult>> { let n_coords = cs.size()?; @@ -16,16 +13,16 @@ fn coords_seq_to_vec_position(cs: &CoordSeq) -> GResult>> { Ok(coords) } -macro_rules! impl_try_into { +macro_rules! impl_try_from_geojson { ($ty_name:ident $(,$lt:lifetime)?) => ( -impl<'a$(,$lt)?> TryInto for $ty_name<'a$(,$lt)?> { - type Err = Error; +impl<'a$(,$lt)?> TryFrom<$ty_name<'a$(,$lt)?>> for Geometry { + type Error = Error; - fn try_into(self) -> Result { - let _type = self.geometry_type(); + fn try_from(other: $ty_name<'a$(,$lt)?>) -> Result { + let _type = other.geometry_type(); match _type { GeometryTypes::Point => { - let coord_seq = self.get_coord_seq()?; + let coord_seq = other.get_coord_seq()?; Ok(Geometry::new( Value::Point( vec![ @@ -34,52 +31,52 @@ impl<'a$(,$lt)?> TryInto for $ty_name<'a$(,$lt)?> { ] ) )) - }, + } GeometryTypes::MultiPoint => { - let n_pts = self.get_num_geometries()?; + let n_pts = other.get_num_geometries()?; let mut coords = Vec::with_capacity(n_pts); for i in 0..n_pts { - let coord_seq = self.get_geometry_n(i)?.get_coord_seq()?; + let coord_seq = other.get_geometry_n(i)?.get_coord_seq()?; coords.push(vec![ coord_seq.get_x(0)?, coord_seq.get_y(0)?, ]); } Ok(Geometry::new(Value::MultiPoint(coords))) - }, + } GeometryTypes::LineString | GeometryTypes::LinearRing => { - let cs = self.get_coord_seq()?; + let cs = other.get_coord_seq()?; let coords = coords_seq_to_vec_position(&cs)?; Ok(Geometry::new(Value::LineString(coords))) - }, + } GeometryTypes::MultiLineString => { - let n_lines = self.get_num_geometries()?; + let n_lines = other.get_num_geometries()?; let mut result_lines = Vec::with_capacity(n_lines); for i in 0..n_lines { - let cs = self.get_geometry_n(i)?.get_coord_seq()?; + let cs = other.get_geometry_n(i)?.get_coord_seq()?; result_lines.push(coords_seq_to_vec_position(&(cs))?); } Ok(Geometry::new(Value::MultiLineString(result_lines))) - }, + } GeometryTypes::Polygon => { - let nb_interiors = self.get_num_interior_rings()?; + let nb_interiors = other.get_num_interior_rings()?; let mut rings = Vec::with_capacity(nb_interiors + 1usize); // Exterior ring to coordinates rings.push(coords_seq_to_vec_position(&( - self.get_exterior_ring()?.get_coord_seq()?))?); + other.get_exterior_ring()?.get_coord_seq()?))?); // Interior rings to coordinates for ix_interior in 0..nb_interiors { rings.push(coords_seq_to_vec_position( - &(self.get_interior_ring_n(ix_interior as u32)?.get_coord_seq()?))?); + &(other.get_interior_ring_n(ix_interior as u32)?.get_coord_seq()?))?); } Ok(Geometry::new(Value::Polygon(rings))) - }, + } GeometryTypes::MultiPolygon => { - let n_polygs = self.get_num_geometries()?; + let n_polygs = other.get_num_geometries()?; let mut result_polygs = Vec::with_capacity(n_polygs); for i in 0..n_polygs { - let polyg = self.get_geometry_n(i)?; + let polyg = other.get_geometry_n(i)?; let nb_interiors = polyg.get_num_interior_rings()?; let mut rings = Vec::with_capacity(nb_interiors + 1usize); @@ -94,17 +91,17 @@ impl<'a$(,$lt)?> TryInto for $ty_name<'a$(,$lt)?> { result_polygs.push(rings); } Ok(Geometry::new(Value::MultiPolygon(result_polygs))) - }, + } GeometryTypes::GeometryCollection => { - let n_geoms = self.get_num_geometries()?; + let n_geoms = other.get_num_geometries()?; let mut result_geoms = Vec::with_capacity(n_geoms); for i in 0..n_geoms { - let g = self.get_geometry_n(i)?; + let g = other.get_geometry_n(i)?; let geojsongeom: Geometry = g.try_into()?; result_geoms.push(geojsongeom); } Ok(Geometry::new(Value::GeometryCollection(result_geoms))) - }, + } _ => unreachable!(), } } @@ -112,15 +109,16 @@ impl<'a$(,$lt)?> TryInto for $ty_name<'a$(,$lt)?> { ); } -impl_try_into!(GGeometry); -impl_try_into!(ConstGeometry, 'c); +impl_try_from_geojson!(GGeometry); +impl_try_from_geojson!(ConstGeometry, 'c); #[cfg(test)] mod test { - use crate::to_geojson::TryInto; use crate::Geometry as GGeometry; use geojson::{Geometry, Value}; + use std::convert::TryInto; + #[test] fn geom_to_geojson_point() { let pt = "POINT(1 1)"; diff --git a/src/voronoi.rs b/src/voronoi.rs index c512269..ec80215 100644 --- a/src/voronoi.rs +++ b/src/voronoi.rs @@ -1,9 +1,9 @@ use crate::{Geom, Geometry as GGeometry}; use error::Error; -use from_geo::TryInto; use geo_types::{Geometry, GeometryCollection, Point, Polygon}; use std::borrow::Borrow; +use std::convert::TryInto; /// Available using the `geo` feature. pub fn compute_voronoi>>( @@ -24,8 +24,7 @@ pub fn compute_voronoi>>( .and_then(|gc: GeometryCollection| { gc.0.into_iter() .map(|g| { - // We use this syntax to not conflict with "from_geo::TryInto" - ::std::convert::TryInto::try_into(g) + g.try_into() .map_err(|e| Error::ConversionError(format!("invalid inner geometry type: {}", e))) }) .collect()