Skip to main content

solverforge_maps/routing/
error.rs

1//! Error types for routing operations.
2
3use std::fmt;
4
5use super::coord::Coord;
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum CoordError {
9    LatOutOfRange { value: f64 },
10    LngOutOfRange { value: f64 },
11    LatNaN,
12    LngNaN,
13    LatInfinite { value: f64 },
14    LngInfinite { value: f64 },
15}
16
17impl fmt::Display for CoordError {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        match self {
20            CoordError::LatOutOfRange { value } => {
21                write!(f, "latitude {} out of valid range [-90, 90]", value)
22            }
23            CoordError::LngOutOfRange { value } => {
24                write!(f, "longitude {} out of valid range [-180, 180]", value)
25            }
26            CoordError::LatNaN => write!(f, "latitude is NaN"),
27            CoordError::LngNaN => write!(f, "longitude is NaN"),
28            CoordError::LatInfinite { value } => write!(f, "latitude {} is infinite", value),
29            CoordError::LngInfinite { value } => write!(f, "longitude {} is infinite", value),
30        }
31    }
32}
33
34impl std::error::Error for CoordError {}
35
36#[derive(Debug, Clone, PartialEq)]
37pub enum BBoxError {
38    MinLatGreaterThanMax { min: f64, max: f64 },
39    MinLngGreaterThanMax { min: f64, max: f64 },
40    LatOutOfRange { value: f64 },
41    LngOutOfRange { value: f64 },
42    NaN { field: &'static str },
43    Infinite { field: &'static str, value: f64 },
44}
45
46impl fmt::Display for BBoxError {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        match self {
49            BBoxError::MinLatGreaterThanMax { min, max } => {
50                write!(f, "min_lat {} is greater than max_lat {}", min, max)
51            }
52            BBoxError::MinLngGreaterThanMax { min, max } => {
53                write!(f, "min_lng {} is greater than max_lng {}", min, max)
54            }
55            BBoxError::LatOutOfRange { value } => {
56                write!(f, "latitude {} out of valid range [-90, 90]", value)
57            }
58            BBoxError::LngOutOfRange { value } => {
59                write!(f, "longitude {} out of valid range [-180, 180]", value)
60            }
61            BBoxError::NaN { field } => write!(f, "{} is NaN", field),
62            BBoxError::Infinite { field, value } => write!(f, "{} {} is infinite", field, value),
63        }
64    }
65}
66
67impl std::error::Error for BBoxError {}
68
69#[derive(Debug)]
70pub enum RoutingError {
71    Network(String),
72    Parse(String),
73    Io(std::io::Error),
74    SnapFailed {
75        coord: Coord,
76        nearest_distance_m: Option<f64>,
77    },
78    NoPath {
79        from: Coord,
80        to: Coord,
81    },
82    InvalidCoordinate {
83        error: CoordError,
84    },
85    Cancelled,
86}
87
88impl fmt::Display for RoutingError {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        match self {
91            RoutingError::Network(msg) => write!(f, "Network error: {}", msg),
92            RoutingError::Parse(msg) => write!(f, "Parse error: {}", msg),
93            RoutingError::Io(e) => write!(f, "I/O error: {}", e),
94            RoutingError::SnapFailed {
95                coord,
96                nearest_distance_m,
97            } => match nearest_distance_m {
98                Some(dist) => write!(
99                    f,
100                    "Failed to snap coordinate ({}, {}) to road network; nearest node is {:.1}m away",
101                    coord.lat, coord.lng, dist
102                ),
103                None => write!(
104                    f,
105                    "Failed to snap coordinate ({}, {}) to road network; no nodes in network",
106                    coord.lat, coord.lng
107                ),
108            },
109            RoutingError::NoPath { from, to } => write!(
110                f,
111                "No path found from ({}, {}) to ({}, {})",
112                from.lat, from.lng, to.lat, to.lng
113            ),
114            RoutingError::InvalidCoordinate { error } => {
115                write!(f, "Invalid coordinate: {}", error)
116            }
117            RoutingError::Cancelled => write!(f, "Operation was cancelled"),
118        }
119    }
120}
121
122impl std::error::Error for RoutingError {}
123
124impl From<std::io::Error> for RoutingError {
125    fn from(e: std::io::Error) -> Self {
126        RoutingError::Io(e)
127    }
128}
129
130impl From<CoordError> for RoutingError {
131    fn from(e: CoordError) -> Self {
132        RoutingError::InvalidCoordinate { error: e }
133    }
134}