From 56c6a6a5a153b58a85b322d7d7422d677ab448b8 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 26 Jan 2021 09:42:29 -0600 Subject: [PATCH] geom enum impl --- geo/src/algorithm/area.rs | 31 ++------------ geo/src/algorithm/bounding_rect.rs | 15 +------ geo/src/algorithm/contains/geometry.rs | 15 +------ geo/src/algorithm/coords_iter.rs | 18 ++------ geo/src/algorithm/dimensions.rs | 47 ++------------------- geo/src/algorithm/intersects/collections.rs | 15 +------ geo/src/types.rs | 28 ++++++++++++ 7 files changed, 44 insertions(+), 125 deletions(-) diff --git a/geo/src/algorithm/area.rs b/geo/src/algorithm/area.rs index 7b77533b5d..34df2aed64 100644 --- a/geo/src/algorithm/area.rs +++ b/geo/src/algorithm/area.rs @@ -236,34 +236,9 @@ impl Area for Geometry where T: CoordFloat, { - fn signed_area(&self) -> T { - match self { - Geometry::Point(g) => g.signed_area(), - Geometry::Line(g) => g.signed_area(), - Geometry::LineString(g) => g.signed_area(), - Geometry::Polygon(g) => g.signed_area(), - Geometry::MultiPoint(g) => g.signed_area(), - Geometry::MultiLineString(g) => g.signed_area(), - Geometry::MultiPolygon(g) => g.signed_area(), - Geometry::GeometryCollection(g) => g.signed_area(), - Geometry::Rect(g) => g.signed_area(), - Geometry::Triangle(g) => g.signed_area(), - } - } - - fn unsigned_area(&self) -> T { - match self { - Geometry::Point(g) => g.unsigned_area(), - Geometry::Line(g) => g.unsigned_area(), - Geometry::LineString(g) => g.unsigned_area(), - Geometry::Polygon(g) => g.unsigned_area(), - Geometry::MultiPoint(g) => g.unsigned_area(), - Geometry::MultiLineString(g) => g.unsigned_area(), - Geometry::MultiPolygon(g) => g.unsigned_area(), - Geometry::GeometryCollection(g) => g.unsigned_area(), - Geometry::Rect(g) => g.unsigned_area(), - Geometry::Triangle(g) => g.unsigned_area(), - } + crate::geometry_enum_impl! { + fn signed_area(&self) -> T; + fn unsigned_area(&self) -> T; } } diff --git a/geo/src/algorithm/bounding_rect.rs b/geo/src/algorithm/bounding_rect.rs index e82c558e54..e06a7b81af 100644 --- a/geo/src/algorithm/bounding_rect.rs +++ b/geo/src/algorithm/bounding_rect.rs @@ -161,19 +161,8 @@ where { type Output = Option>; - fn bounding_rect(&self) -> Self::Output { - match self { - Geometry::Point(g) => Some(g.bounding_rect()), - Geometry::Line(g) => Some(g.bounding_rect()), - Geometry::LineString(g) => g.bounding_rect(), - Geometry::Polygon(g) => g.bounding_rect(), - Geometry::MultiPoint(g) => g.bounding_rect(), - Geometry::MultiLineString(g) => g.bounding_rect(), - Geometry::MultiPolygon(g) => g.bounding_rect(), - Geometry::GeometryCollection(g) => g.bounding_rect(), - Geometry::Rect(g) => Some(g.bounding_rect()), - Geometry::Triangle(g) => Some(g.bounding_rect()), - } + crate::geometry_enum_impl! { + fn bounding_rect(&self) -> Self::Output; } } diff --git a/geo/src/algorithm/contains/geometry.rs b/geo/src/algorithm/contains/geometry.rs index d5d957a923..1f75388b58 100644 --- a/geo/src/algorithm/contains/geometry.rs +++ b/geo/src/algorithm/contains/geometry.rs @@ -9,19 +9,8 @@ impl Contains> for Geometry where T: GeoNum, { - fn contains(&self, coord: &Coordinate) -> bool { - match self { - Geometry::Point(g) => g.contains(coord), - Geometry::Line(g) => g.contains(coord), - Geometry::LineString(g) => g.contains(coord), - Geometry::Polygon(g) => g.contains(coord), - Geometry::MultiPoint(g) => g.contains(coord), - Geometry::MultiLineString(g) => g.contains(coord), - Geometry::MultiPolygon(g) => g.contains(coord), - Geometry::GeometryCollection(g) => g.contains(coord), - Geometry::Rect(g) => g.contains(coord), - Geometry::Triangle(g) => g.contains(coord), - } + geometry_enum_impl! { + fn contains(&self, coord: &Coordinate) -> bool; } } diff --git a/geo/src/algorithm/coords_iter.rs b/geo/src/algorithm/coords_iter.rs index 6509c0b6d2..b899927131 100644 --- a/geo/src/algorithm/coords_iter.rs +++ b/geo/src/algorithm/coords_iter.rs @@ -395,21 +395,9 @@ impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Geometry { Geometry::Triangle(g) => GeometryCoordsIter::Triangle(g.coords_iter()), } } - - /// Return the number of coordinates in the `Geometry`. - fn coords_count(&'a self) -> usize { - match self { - Geometry::Point(g) => g.coords_count(), - Geometry::Line(g) => g.coords_count(), - Geometry::LineString(g) => g.coords_count(), - Geometry::Polygon(g) => g.coords_count(), - Geometry::MultiPoint(g) => g.coords_count(), - Geometry::MultiLineString(g) => g.coords_count(), - Geometry::MultiPolygon(g) => g.coords_count(), - Geometry::GeometryCollection(g) => g.coords_count(), - Geometry::Rect(g) => g.coords_count(), - Geometry::Triangle(g) => g.coords_count(), - } + crate::geometry_enum_impl! { + /// Return the number of coordinates in the `Geometry`. + fn coords_count(&'a self) -> usize; } fn exterior_coords_iter(&'a self) -> Self::ExteriorIter { diff --git a/geo/src/algorithm/dimensions.rs b/geo/src/algorithm/dimensions.rs index 066df3dc51..4336428530 100644 --- a/geo/src/algorithm/dimensions.rs +++ b/geo/src/algorithm/dimensions.rs @@ -132,49 +132,10 @@ pub trait HasDimensions { } impl HasDimensions for Geometry { - fn is_empty(&self) -> bool { - match self { - Geometry::Point(g) => g.is_empty(), - Geometry::Line(g) => g.is_empty(), - Geometry::LineString(g) => g.is_empty(), - Geometry::Polygon(g) => g.is_empty(), - Geometry::MultiPoint(g) => g.is_empty(), - Geometry::MultiLineString(g) => g.is_empty(), - Geometry::MultiPolygon(g) => g.is_empty(), - Geometry::GeometryCollection(g) => g.is_empty(), - Geometry::Rect(g) => g.is_empty(), - Geometry::Triangle(g) => g.is_empty(), - } - } - - fn dimensions(&self) -> Dimensions { - match self { - Geometry::Point(g) => g.dimensions(), - Geometry::Line(g) => g.dimensions(), - Geometry::LineString(g) => g.dimensions(), - Geometry::Polygon(g) => g.dimensions(), - Geometry::MultiPoint(g) => g.dimensions(), - Geometry::MultiLineString(g) => g.dimensions(), - Geometry::MultiPolygon(g) => g.dimensions(), - Geometry::GeometryCollection(g) => g.dimensions(), - Geometry::Rect(g) => g.dimensions(), - Geometry::Triangle(g) => g.dimensions(), - } - } - - fn boundary_dimensions(&self) -> Dimensions { - match self { - Geometry::Point(g) => g.boundary_dimensions(), - Geometry::Line(g) => g.boundary_dimensions(), - Geometry::LineString(g) => g.boundary_dimensions(), - Geometry::Polygon(g) => g.boundary_dimensions(), - Geometry::MultiPoint(g) => g.boundary_dimensions(), - Geometry::MultiLineString(g) => g.boundary_dimensions(), - Geometry::MultiPolygon(g) => g.boundary_dimensions(), - Geometry::GeometryCollection(g) => g.boundary_dimensions(), - Geometry::Rect(g) => g.boundary_dimensions(), - Geometry::Triangle(g) => g.boundary_dimensions(), - } + crate::geometry_enum_impl! { + fn is_empty(&self) -> bool; + fn dimensions(&self) -> Dimensions; + fn boundary_dimensions(&self) -> Dimensions; } } diff --git a/geo/src/algorithm/intersects/collections.rs b/geo/src/algorithm/intersects/collections.rs index 25b5557fd7..1d7ed9162f 100644 --- a/geo/src/algorithm/intersects/collections.rs +++ b/geo/src/algorithm/intersects/collections.rs @@ -14,19 +14,8 @@ where Polygon: Intersects, MultiPolygon: Intersects, { - fn intersects(&self, rhs: &G) -> bool { - match self { - Geometry::Point(geom) => geom.intersects(rhs), - Geometry::MultiPoint(geom) => geom.intersects(rhs), - Geometry::Line(geom) => geom.intersects(rhs), - Geometry::LineString(geom) => geom.intersects(rhs), - Geometry::MultiLineString(geom) => geom.intersects(rhs), - Geometry::Triangle(geom) => geom.intersects(rhs), - Geometry::Rect(geom) => geom.intersects(rhs), - Geometry::Polygon(geom) => geom.intersects(rhs), - Geometry::MultiPolygon(geom) => geom.intersects(rhs), - Geometry::GeometryCollection(geom) => geom.intersects(rhs), - } + geometry_enum_impl! { + fn intersects(&self, rhs: &G) -> bool; } } symmetric_intersects_impl!(Coordinate, Geometry); diff --git a/geo/src/types.rs b/geo/src/types.rs index caef2e3a6b..16c16e3c7f 100644 --- a/geo/src/types.rs +++ b/geo/src/types.rs @@ -36,3 +36,31 @@ impl Closest { } } } + +#[macro_export] +macro_rules! geometry_enum_impl { + ( + $( + $(#[$outer:meta])* + fn $func_name: ident(&$($self_life:lifetime)?self $(, $arg_name: ident: $arg_type: ty)*) -> $return: ty; + )+ + ) => { + $( + $(#[$outer])* + fn $func_name(&$($self_life)? self, $($arg_name: $arg_type),*) -> $return { + match self { + Geometry::Point(g) => g.$func_name($($arg_name),*).into(), + Geometry::Line(g) => g.$func_name($($arg_name),*).into(), + Geometry::LineString(g) => g.$func_name($($arg_name),*).into(), + Geometry::Polygon(g) => g.$func_name($($arg_name),*).into(), + Geometry::MultiPoint(g) => g.$func_name($($arg_name),*).into(), + Geometry::MultiLineString(g) => g.$func_name($($arg_name),*).into(), + Geometry::MultiPolygon(g) => g.$func_name($($arg_name),*).into(), + Geometry::GeometryCollection(g) => g.$func_name($($arg_name),*).into(), + Geometry::Rect(g) => g.$func_name($($arg_name),*).into(), + Geometry::Triangle(g) => g.$func_name($($arg_name),*).into(), + } + } + )+ + }; +}