Skip to main content

kasane_logic/
error.rs

1use std::{error, fmt};
2
3/// 本クレートで発生し得るエラーを表す最上位の型。
4#[derive(Debug, Clone, PartialEq)]
5pub enum Error {
6    /// 空間IDまわりのエラー。
7    SpatialId(SpatialIdError),
8
9    /// Geometry まわりのエラー。
10    Geometry(GeometryError),
11}
12
13/// Geometry 関連で発生するエラー。
14#[derive(Debug, Clone, PartialEq)]
15pub enum GeometryError {
16    /// 緯度が有効範囲外であることを表す。
17    LatitudeOutOfRange { latitude: f64 },
18
19    /// 経度が有効範囲外であることを表す。
20    LongitudeOutOfRange { longitude: f64 },
21
22    /// 高度が有効範囲外であることを表す。
23    AltitudeOutOfRange { altitude: f64 },
24
25    /// Solid が watertight ではないことを表す。
26    SolidNotWatertight {
27        /// 問題のあるエッジの数(奇数回しか出現しなかったエッジの数)
28        open_edge_count: usize,
29    },
30}
31
32/// SpatialId 関連で発生するエラー。
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub enum SpatialIdError {
35    /// ズームレベルが有効範囲(0..=31)外であることを示す。
36    ZOutOfRange { z: u8 },
37
38    /// ある操作に対して、現在のズームレベルと要求されたズームレベルの上下関係が不正であることを示す。
39    ///
40    /// たとえば、より深いズームレベルを要求する操作に対して浅いズームレベルを指定した場合などに使う。
41    ZoomLevelTransitionOutOfRange { current_z: u8, target_z: u8 },
42
43    /// 高度方向インデックス `f` が、指定されたズームレベルに対して有効範囲外であることを示す。
44    FOutOfRange { z: u8, f: i32 },
45
46    /// X 方向インデックスが、指定されたズームレベルに対して有効範囲外であることを示す。
47    XOutOfRange { z: u8, x: u32 },
48
49    /// Y 方向インデックスが、指定されたズームレベルに対して有効範囲外であることを示す。
50    YOutOfRange { z: u8, y: u32 },
51
52    /// 時間方向が0-u64::MAXの有効範囲外であることを示す。
53    /// 0=<i×t=<u64::MAXを満たす必要がある
54    TOutOfRange { i: u64, t: u64 },
55
56    /// 時間間隔 `i` に 0 を指定した場合のエラー。
57    TIntervalZero,
58}
59
60impl From<GeometryError> for Error {
61    fn from(value: GeometryError) -> Self {
62        Self::Geometry(value)
63    }
64}
65
66impl From<SpatialIdError> for Error {
67    fn from(value: SpatialIdError) -> Self {
68        Self::SpatialId(value)
69    }
70}
71
72impl fmt::Display for Error {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        match self {
75            Error::SpatialId(inner) => inner.fmt(f),
76            Error::Geometry(inner) => inner.fmt(f),
77        }
78    }
79}
80
81impl fmt::Display for GeometryError {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        match self {
84            GeometryError::LatitudeOutOfRange { latitude } => {
85                write!(
86                    f,
87                    "Latitude '{}' is out of range (valid: -85.0511..=85.0511)",
88                    latitude
89                )
90            }
91            GeometryError::LongitudeOutOfRange { longitude } => {
92                write!(
93                    f,
94                    "Longitude '{}' is out of range (valid: -180.0..=180.0)",
95                    longitude
96                )
97            }
98            GeometryError::AltitudeOutOfRange { altitude } => {
99                write!(
100                    f,
101                    "Altitude '{}' is out of range (valid: -33,554,432.0..=33,554,432.0)",
102                    altitude
103                )
104            }
105            GeometryError::SolidNotWatertight { open_edge_count } => {
106                write!(
107                    f,
108                    "Solid is not watertight (closed). Found {} open edges.",
109                    open_edge_count
110                )
111            }
112        }
113    }
114}
115
116impl fmt::Display for SpatialIdError {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        match self {
119            SpatialIdError::ZOutOfRange { z } => {
120                write!(f, "ZoomLevel '{}' is out of range (valid: 0..=60)", z)
121            }
122            SpatialIdError::ZoomLevelTransitionOutOfRange {
123                current_z,
124                target_z,
125            } => {
126                write!(
127                    f,
128                    "Target zoom level '{}' is invalid for current zoom level '{}'",
129                    target_z, current_z
130                )
131            }
132            SpatialIdError::FOutOfRange { z, f: fv } => {
133                write!(
134                    f,
135                    "F coordinate '{}' is out of range for ZoomLevel '{}'",
136                    fv, z
137                )
138            }
139            SpatialIdError::XOutOfRange { z, x } => {
140                write!(
141                    f,
142                    "X coordinate '{}' is out of range for ZoomLevel '{}'",
143                    x, z
144                )
145            }
146            SpatialIdError::YOutOfRange { z, y } => {
147                write!(
148                    f,
149                    "Y coordinate '{}' is out of range for ZoomLevel '{}'",
150                    y, z
151                )
152            }
153            SpatialIdError::TOutOfRange { i, t } => {
154                write!(f, "i × t overflows u64 (i={}, t={}).", i, t)
155            }
156            SpatialIdError::TIntervalZero => {
157                write!(f, "Time interval i cannot be set to 0 ")
158            }
159        }
160    }
161}
162
163impl error::Error for Error {}
164
165impl error::Error for GeometryError {}
166
167impl error::Error for SpatialIdError {}