geo/algorithm/validation/
multi_point.rs1use super::{GeometryIndex, InvalidPoint, Validation};
2use crate::{GeoFloat, MultiPoint};
3
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum InvalidMultiPoint {
9 InvalidPoint(GeometryIndex, InvalidPoint),
11}
12
13impl fmt::Display for InvalidMultiPoint {
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 match self {
16 InvalidMultiPoint::InvalidPoint(idx, err) => {
17 write!(f, "point at index {} is invalid: {}", idx.0, err)
18 }
19 }
20 }
21}
22
23impl std::error::Error for InvalidMultiPoint {}
24
25impl<F: GeoFloat> Validation for MultiPoint<F> {
26 type Error = InvalidMultiPoint;
27
28 fn visit_validation<T>(
29 &self,
30 mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
31 ) -> Result<(), T> {
32 for (i, point) in self.0.iter().enumerate() {
33 point.visit_validation(Box::new(&mut |invalid_point| {
34 let err = InvalidMultiPoint::InvalidPoint(GeometryIndex(i), invalid_point);
35 handle_validation_error(err)
36 }))?;
37 }
38 Ok(())
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::algorithm::validation::{assert_valid, assert_validation_errors};
46 use crate::{geometry::*, wkt};
47
48 #[test]
49 fn test_multipoint_valid() {
50 let mp = wkt!(MULTIPOINT(0. 0.,1. 1.));
51 assert_valid!(&mp);
52 }
53
54 #[test]
55 fn test_multipoint_invalid() {
56 let mp = MultiPoint(vec![
57 Point::new(0., f64::INFINITY),
58 Point::new(f64::NAN, 1.),
59 ]);
60 assert_validation_errors!(
61 &mp,
62 vec![
63 InvalidMultiPoint::InvalidPoint(GeometryIndex(0), InvalidPoint::NonFiniteCoord),
64 InvalidMultiPoint::InvalidPoint(GeometryIndex(1), InvalidPoint::NonFiniteCoord)
65 ]
66 );
67 }
68}