use crate::{
CoordinateType, GeometryCollection, Line, LineString, MultiLineString, MultiPoint,
MultiPolygon, Point, Polygon,
};
use num_traits::Float;
use std::convert::TryFrom;
use std::error::Error;
use std::fmt;
#[derive(PartialEq, Clone, Debug, Hash)]
pub enum Geometry<T>
where
T: CoordinateType,
{
Point(Point<T>),
Line(Line<T>),
LineString(LineString<T>),
Polygon(Polygon<T>),
MultiPoint(MultiPoint<T>),
MultiLineString(MultiLineString<T>),
MultiPolygon(MultiPolygon<T>),
GeometryCollection(GeometryCollection<T>),
}
impl<T: CoordinateType> From<Point<T>> for Geometry<T> {
fn from(x: Point<T>) -> Geometry<T> {
Geometry::Point(x)
}
}
impl<T: CoordinateType> From<Line<T>> for Geometry<T> {
fn from(x: Line<T>) -> Geometry<T> {
Geometry::Line(x)
}
}
impl<T: CoordinateType> From<LineString<T>> for Geometry<T> {
fn from(x: LineString<T>) -> Geometry<T> {
Geometry::LineString(x)
}
}
impl<T: CoordinateType> From<Polygon<T>> for Geometry<T> {
fn from(x: Polygon<T>) -> Geometry<T> {
Geometry::Polygon(x)
}
}
impl<T: CoordinateType> From<MultiPoint<T>> for Geometry<T> {
fn from(x: MultiPoint<T>) -> Geometry<T> {
Geometry::MultiPoint(x)
}
}
impl<T: CoordinateType> From<MultiLineString<T>> for Geometry<T> {
fn from(x: MultiLineString<T>) -> Geometry<T> {
Geometry::MultiLineString(x)
}
}
impl<T: CoordinateType> From<MultiPolygon<T>> for Geometry<T> {
fn from(x: MultiPolygon<T>) -> Geometry<T> {
Geometry::MultiPolygon(x)
}
}
impl<T: CoordinateType> Geometry<T> {
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<Point>"
)]
pub fn into_point(self) -> Option<Point<T>> {
if let Geometry::Point(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<LineString>"
)]
pub fn into_line_string(self) -> Option<LineString<T>> {
if let Geometry::LineString(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<Line>"
)]
pub fn into_line(self) -> Option<Line<T>> {
if let Geometry::Line(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<Polygon>"
)]
pub fn into_polygon(self) -> Option<Polygon<T>> {
if let Geometry::Polygon(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<MultiPoint>"
)]
pub fn into_multi_point(self) -> Option<MultiPoint<T>> {
if let Geometry::MultiPoint(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<MultiLineString>"
)]
pub fn into_multi_line_string(self) -> Option<MultiLineString<T>> {
if let Geometry::MultiLineString(x) = self {
Some(x)
} else {
None
}
}
#[deprecated(
note = "Will be removed in an upcoming version. Switch to std::convert::TryInto<MultiPolygon>"
)]
pub fn into_multi_polygon(self) -> Option<MultiPolygon<T>> {
if let Geometry::MultiPolygon(x) = self {
Some(x)
} else {
None
}
}
}
#[derive(Debug)]
pub struct FailedToConvertError;
impl fmt::Display for FailedToConvertError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Could not convert from enum member to concrete type")
}
}
impl Error for FailedToConvertError {
fn description(&self) -> &str {
"Could not convert from enum member to concrete type"
}
}
impl<T> TryFrom<Geometry<T>> for Point<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<Point<T>, Self::Error> {
match geom {
Geometry::Point(p) => Ok(p),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for Line<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<Line<T>, Self::Error> {
match geom {
Geometry::Line(l) => Ok(l),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for LineString<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<LineString<T>, Self::Error> {
match geom {
Geometry::LineString(ls) => Ok(ls),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for Polygon<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<Polygon<T>, Self::Error> {
match geom {
Geometry::Polygon(ls) => Ok(ls),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for MultiPoint<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<MultiPoint<T>, Self::Error> {
match geom {
Geometry::MultiPoint(mp) => Ok(mp),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for MultiLineString<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<MultiLineString<T>, Self::Error> {
match geom {
Geometry::MultiLineString(mls) => Ok(mls),
_ => Err(FailedToConvertError),
}
}
}
impl<T> TryFrom<Geometry<T>> for MultiPolygon<T>
where
T: Float,
{
type Error = FailedToConvertError;
fn try_from(geom: Geometry<T>) -> Result<MultiPolygon<T>, Self::Error> {
match geom {
Geometry::MultiPolygon(mp) => Ok(mp),
_ => Err(FailedToConvertError),
}
}
}