geo/algorithm/validation/
geometry.rs

1use super::Validation;
2use super::{
3    InvalidGeometryCollection, InvalidLine, InvalidLineString, InvalidMultiLineString,
4    InvalidMultiPoint, InvalidMultiPolygon, InvalidPoint, InvalidPolygon, InvalidRect,
5    InvalidTriangle,
6};
7use crate::{GeoFloat, Geometry};
8
9use crate::geometry_cow::GeometryCow;
10use std::fmt;
11
12/// A [`Geometry`] is valid if its inner variant is valid.
13/// e.g. `Geometry::Polygon(polygon)` is valid if and only if `polygon` is valid.
14#[derive(Debug, Clone, PartialEq)]
15pub enum InvalidGeometry {
16    InvalidPoint(InvalidPoint),
17    InvalidLine(InvalidLine),
18    InvalidLineString(InvalidLineString),
19    InvalidPolygon(InvalidPolygon),
20    InvalidMultiPoint(InvalidMultiPoint),
21    InvalidMultiLineString(InvalidMultiLineString),
22    InvalidMultiPolygon(InvalidMultiPolygon),
23    InvalidGeometryCollection(InvalidGeometryCollection),
24    InvalidRect(InvalidRect),
25    InvalidTriangle(InvalidTriangle),
26}
27
28impl fmt::Display for InvalidGeometry {
29    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30        match self {
31            InvalidGeometry::InvalidPoint(err) => write!(f, "{}", err),
32            InvalidGeometry::InvalidLine(err) => write!(f, "{}", err),
33            InvalidGeometry::InvalidLineString(err) => write!(f, "{}", err),
34            InvalidGeometry::InvalidPolygon(err) => write!(f, "{}", err),
35            InvalidGeometry::InvalidMultiPoint(err) => write!(f, "{}", err),
36            InvalidGeometry::InvalidMultiLineString(err) => write!(f, "{}", err),
37            InvalidGeometry::InvalidMultiPolygon(err) => write!(f, "{}", err),
38            InvalidGeometry::InvalidGeometryCollection(err) => write!(f, "{}", err),
39            InvalidGeometry::InvalidRect(err) => write!(f, "{}", err),
40            InvalidGeometry::InvalidTriangle(err) => write!(f, "{}", err),
41        }
42    }
43}
44
45impl std::error::Error for InvalidGeometry {
46    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
47        match self {
48            InvalidGeometry::InvalidPoint(err) => Some(err),
49            InvalidGeometry::InvalidLine(err) => Some(err),
50            InvalidGeometry::InvalidLineString(err) => Some(err),
51            InvalidGeometry::InvalidPolygon(err) => Some(err),
52            InvalidGeometry::InvalidMultiPoint(err) => Some(err),
53            InvalidGeometry::InvalidMultiLineString(err) => Some(err),
54            InvalidGeometry::InvalidMultiPolygon(err) => Some(err),
55            InvalidGeometry::InvalidGeometryCollection(err) => Some(err),
56            InvalidGeometry::InvalidRect(err) => Some(err),
57            InvalidGeometry::InvalidTriangle(err) => Some(err),
58        }
59    }
60}
61
62impl<F: GeoFloat> Validation for Geometry<F> {
63    type Error = InvalidGeometry;
64
65    fn visit_validation<T>(
66        &self,
67        mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
68    ) -> Result<(), T> {
69        match self {
70            Geometry::Point(g) => g.visit_validation(Box::new(|err| {
71                handle_validation_error(InvalidGeometry::InvalidPoint(err))
72            }))?,
73            Geometry::Line(g) => g.visit_validation(Box::new(|err| {
74                handle_validation_error(InvalidGeometry::InvalidLine(err))
75            }))?,
76            Geometry::LineString(g) => g.visit_validation(Box::new(|err| {
77                handle_validation_error(InvalidGeometry::InvalidLineString(err))
78            }))?,
79            Geometry::Polygon(g) => g.visit_validation(Box::new(|err| {
80                handle_validation_error(InvalidGeometry::InvalidPolygon(err))
81            }))?,
82            Geometry::MultiPoint(g) => g.visit_validation(Box::new(|err| {
83                handle_validation_error(InvalidGeometry::InvalidMultiPoint(err))
84            }))?,
85            Geometry::MultiLineString(g) => g.visit_validation(Box::new(|err| {
86                handle_validation_error(InvalidGeometry::InvalidMultiLineString(err))
87            }))?,
88            Geometry::MultiPolygon(g) => g.visit_validation(Box::new(|err| {
89                handle_validation_error(InvalidGeometry::InvalidMultiPolygon(err))
90            }))?,
91            Geometry::GeometryCollection(g) => g.visit_validation(Box::new(|err| {
92                handle_validation_error(InvalidGeometry::InvalidGeometryCollection(err))
93            }))?,
94            Geometry::Rect(g) => g.visit_validation(Box::new(|err| {
95                handle_validation_error(InvalidGeometry::InvalidRect(err))
96            }))?,
97            Geometry::Triangle(g) => g.visit_validation(Box::new(|err| {
98                handle_validation_error(InvalidGeometry::InvalidTriangle(err))
99            }))?,
100        }
101        Ok(())
102    }
103}
104
105impl<F: GeoFloat> Validation for GeometryCow<'_, F> {
106    type Error = InvalidGeometry;
107
108    fn visit_validation<T>(
109        &self,
110        mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
111    ) -> Result<(), T> {
112        match self {
113            GeometryCow::Point(g) => g.visit_validation(Box::new(|err| {
114                handle_validation_error(InvalidGeometry::InvalidPoint(err))
115            }))?,
116            GeometryCow::Line(g) => g.visit_validation(Box::new(|err| {
117                handle_validation_error(InvalidGeometry::InvalidLine(err))
118            }))?,
119            GeometryCow::LineString(g) => g.visit_validation(Box::new(|err| {
120                handle_validation_error(InvalidGeometry::InvalidLineString(err))
121            }))?,
122            GeometryCow::Polygon(g) => g.visit_validation(Box::new(|err| {
123                handle_validation_error(InvalidGeometry::InvalidPolygon(err))
124            }))?,
125            GeometryCow::MultiPoint(g) => g.visit_validation(Box::new(|err| {
126                handle_validation_error(InvalidGeometry::InvalidMultiPoint(err))
127            }))?,
128            GeometryCow::MultiLineString(g) => g.visit_validation(Box::new(|err| {
129                handle_validation_error(InvalidGeometry::InvalidMultiLineString(err))
130            }))?,
131            GeometryCow::MultiPolygon(g) => g.visit_validation(Box::new(|err| {
132                handle_validation_error(InvalidGeometry::InvalidMultiPolygon(err))
133            }))?,
134            GeometryCow::GeometryCollection(g) => g.visit_validation(Box::new(|err| {
135                handle_validation_error(InvalidGeometry::InvalidGeometryCollection(err))
136            }))?,
137            GeometryCow::Rect(g) => g.visit_validation(Box::new(|err| {
138                handle_validation_error(InvalidGeometry::InvalidRect(err))
139            }))?,
140            GeometryCow::Triangle(g) => g.visit_validation(Box::new(|err| {
141                handle_validation_error(InvalidGeometry::InvalidTriangle(err))
142            }))?,
143        }
144        Ok(())
145    }
146}