1use std::fmt::{Debug, Display, Formatter};
3
4#[derive(Clone, Hash, PartialEq, Eq)]
6#[non_exhaustive]
7pub enum Error {
8 IncompatibleBoundary(String, String),
10 IndexConversion {
12 source_type: String,
13 target_type: String,
14 value: String,
15 },
16 IndexOverflow { index_type: String, value: String },
18 VerticesContainerFull { attempted: usize, maximum: usize },
20 ResourcePoolFull { attempted: usize, maximum: usize },
22 InvalidGeometry(String),
24 InvalidShell {
26 reason: String,
27 surface_count: usize,
28 },
29 InvalidRing { reason: String, vertex_count: usize },
31 InvalidLineString { reason: String, vertex_count: usize },
33 InvalidReference {
35 element_type: String,
36 index: usize,
37 max_index: usize,
38 },
39 InvalidThemeName { theme_type: String, theme: String },
41 InvalidGeometryType { expected: String, found: String },
43 IncompleteGeometry(String),
45 UnsupportedVersion(String, String),
47 InvalidCityObjectType(String),
49 InvalidJson(String),
51 MissingVersion,
53 UnsupportedCityJSONVersion(String),
55 Import(String),
57}
58
59pub type Result<T> = std::result::Result<T, Error>;
60
61impl Display for Error {
62 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63 match self {
64 Error::IncompatibleBoundary(source_boundarytype, target_boundarytype) => {
65 write!(
66 f,
67 "cannot convert a {source_boundarytype} to a {target_boundarytype}"
68 )
69 }
70 Error::IndexConversion {
71 source_type,
72 target_type,
73 value,
74 } => write!(
75 f,
76 "failed to convert index from {source_type} to {target_type}: value {value}"
77 ),
78 Error::IndexOverflow { index_type, value } => {
79 write!(f, "index overflow for {index_type}: value {value}")
80 }
81 Error::VerticesContainerFull { attempted, maximum } => write!(
82 f,
83 "attempted to store {attempted} vertices in a container with capacity {maximum}"
84 ),
85 Error::ResourcePoolFull { attempted, maximum } => write!(
86 f,
87 "attempted to store {attempted} resources in a pool with maximum {maximum} slots"
88 ),
89 Error::InvalidGeometry(msg) => write!(f, "{msg}"),
90 Error::InvalidShell {
91 reason,
92 surface_count,
93 } => write!(
94 f,
95 "Invalid shell: {reason} (surface count: {surface_count})"
96 ),
97 Error::InvalidRing {
98 reason,
99 vertex_count,
100 } => write!(f, "Invalid ring: {reason} (vertex count: {vertex_count})"),
101 Error::InvalidLineString {
102 reason,
103 vertex_count,
104 } => write!(
105 f,
106 "Invalid linestring: {reason} (vertex count: {vertex_count})"
107 ),
108 Error::InvalidReference {
109 element_type,
110 index,
111 max_index,
112 } => write!(
113 f,
114 "Invalid {element_type} index: {index} (max: {max_index})"
115 ),
116 Error::InvalidThemeName { theme_type, theme } => {
117 write!(f, "Invalid {theme_type} theme name: {theme}")
118 }
119 Error::InvalidGeometryType { expected, found } => {
120 write!(
121 f,
122 "Invalid geometry type: expected {expected}, found {found}"
123 )
124 }
125 Error::IncompleteGeometry(msg) => write!(f, "Incomplete geometry: {msg}"),
126 Error::UnsupportedVersion(v, supported) => {
127 write!(
128 f,
129 "the CityJSON version should be one of {supported}, but got {v}"
130 )
131 }
132 Error::InvalidCityObjectType(v) => write!(f, "invalid CityObject type: {v}"),
133 Error::InvalidJson(msg) => write!(f, "Invalid JSON: {msg}"),
134 Error::MissingVersion => write!(f, "Missing 'version' field in CityJSON document"),
135 Error::UnsupportedCityJSONVersion(version) => {
136 write!(f, "Unsupported CityJSON version: {version}")
137 }
138 Error::Import(msg) => write!(f, "Import error: {msg}"),
139 }
140 }
141}
142
143impl Debug for Error {
144 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{self}")
146 }
147}
148
149impl std::error::Error for Error {}
150
151impl From<std::io::Error> for Error {
152 fn from(value: std::io::Error) -> Self {
153 Error::Import(value.to_string())
154 }
155}