Skip to main content

cityjson_lib/
error.rs

1use std::error;
2use std::fmt::{Debug, Display, Formatter};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum ErrorKind {
6    Io,
7    Syntax,
8    Version,
9    Shape,
10    Unsupported,
11    Model,
12}
13
14pub enum Error {
15    Io(std::io::Error),
16    Syntax(String),
17    CityJSON(cityjson::error::Error),
18    MissingVersion,
19    ExpectedCityJSON(String),
20    ExpectedCityJSONFeature(String),
21    UnsupportedType(String),
22    UnsupportedVersion { found: String, supported: String },
23    Streaming(String),
24    Import(String),
25    UnsupportedFeature(String),
26}
27
28pub type Result<T> = std::result::Result<T, Error>;
29
30impl Error {
31    pub fn kind(&self) -> ErrorKind {
32        match self {
33            Self::Io(_) => ErrorKind::Io,
34            Self::Syntax(_) => ErrorKind::Syntax,
35            Self::CityJSON(_) => ErrorKind::Model,
36            Self::MissingVersion => ErrorKind::Version,
37            Self::ExpectedCityJSON(_) | Self::ExpectedCityJSONFeature(_) => ErrorKind::Shape,
38            Self::UnsupportedType(_)
39            | Self::UnsupportedVersion { .. }
40            | Self::UnsupportedFeature(_) => ErrorKind::Unsupported,
41            Self::Streaming(_) => ErrorKind::Shape,
42            Self::Import(_) => ErrorKind::Model,
43        }
44    }
45}
46
47impl Display for Error {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        match self {
50            Self::Io(error) => write!(f, "I/O error: {error}"),
51            Self::Syntax(error) => write!(f, "JSON error: {error}"),
52            Self::CityJSON(error) => write!(f, "cityjson error: {error}"),
53            Self::MissingVersion => write!(f, "CityJSON object must contain a version member"),
54            Self::ExpectedCityJSON(found) => {
55                write!(f, "expected a CityJSON object, found {found}")
56            }
57            Self::ExpectedCityJSONFeature(found) => {
58                write!(f, "expected a CityJSONFeature object, found {found}")
59            }
60            Self::UnsupportedType(found) => {
61                write!(f, "unsupported CityJSON type: {found}")
62            }
63            Self::UnsupportedVersion { found, supported } => {
64                write!(
65                    f,
66                    "unsupported CityJSON version {found}; supported versions: {supported}"
67                )
68            }
69            Self::Streaming(message) => write!(f, "streaming error: {message}"),
70            Self::Import(message) => write!(f, "import error: {message}"),
71            Self::UnsupportedFeature(message) => write!(f, "unsupported feature: {message}"),
72        }
73    }
74}
75
76impl Debug for Error {
77    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
78        Display::fmt(self, f)
79    }
80}
81
82impl error::Error for Error {}
83
84impl From<std::io::Error> for Error {
85    fn from(value: std::io::Error) -> Self {
86        Self::Io(value)
87    }
88}
89
90impl From<cityjson::error::Error> for Error {
91    fn from(value: cityjson::error::Error) -> Self {
92        Self::CityJSON(value)
93    }
94}
95
96#[cfg(feature = "json")]
97impl From<cityjson_json::Error> for Error {
98    fn from(value: cityjson_json::Error) -> Self {
99        match value {
100            cityjson_json::Error::Json(error) => Self::Syntax(error.to_string()),
101            cityjson_json::Error::Utf8(error) => Self::Syntax(error.to_string()),
102            cityjson_json::Error::CityJson(error) => Self::CityJSON(error),
103            cityjson_json::Error::UnsupportedType(found) => Self::UnsupportedType(found),
104            cityjson_json::Error::UnsupportedVersion(found) => Self::UnsupportedVersion {
105                found,
106                supported: cityjson::CityJSONVersion::V2_0.to_string(),
107            },
108            cityjson_json::Error::MalformedRootObject(reason) => Self::Syntax(reason.to_owned()),
109            cityjson_json::Error::InvalidValue(reason) => Self::Import(reason),
110            cityjson_json::Error::UnsupportedFeature(feature) => {
111                Self::UnsupportedFeature(feature.to_owned())
112            }
113            cityjson_json::Error::UnresolvedCityObjectReference {
114                source_id,
115                target_id,
116                relation,
117            } => Self::Import(format!(
118                "unresolved CityObject {relation} reference from '{source_id}' to '{target_id}'"
119            )),
120        }
121    }
122}