geo/algorithm/validation/
point.rs

1use super::{Validation, utils};
2use crate::{GeoFloat, Point};
3
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq)]
7pub enum InvalidPoint {
8    /// A valid [`Point`] must be finite.
9    NonFiniteCoord,
10}
11
12impl fmt::Display for InvalidPoint {
13    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14        match self {
15            InvalidPoint::NonFiniteCoord => write!(f, "point has non-finite coordinates"),
16        }
17    }
18}
19
20impl std::error::Error for InvalidPoint {}
21
22impl<F: GeoFloat> Validation for Point<F> {
23    type Error = InvalidPoint;
24
25    fn visit_validation<T>(
26        &self,
27        mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
28    ) -> Result<(), T> {
29        if utils::check_coord_is_not_finite(&self.0) {
30            handle_validation_error(InvalidPoint::NonFiniteCoord)?;
31        }
32        Ok(())
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use crate::Point;
40    use crate::algorithm::validation::{assert_valid, assert_validation_errors};
41
42    #[test]
43    fn test_point_valid() {
44        let p = Point::new(0., 0.);
45        assert_valid!(p);
46    }
47
48    #[test]
49    fn test_point_validation_errors() {
50        let p = Point::new(f64::NAN, f64::NAN);
51        assert_validation_errors!(p, vec![InvalidPoint::NonFiniteCoord]);
52    }
53
54    #[test]
55    fn test_point_check_validation() {
56        let p = Point::new(f64::NAN, f64::NAN);
57
58        let err = p.check_validation().unwrap_err();
59        assert_eq!(err, InvalidPoint::NonFiniteCoord);
60    }
61}