1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
use crate::InvalidTilesetError::InvalidTileDimensions;
use std::num::ParseIntError;
use std::{fmt, path::PathBuf};
/// Errors that can occur while decoding csv data.
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum CsvDecodingError {
/// An error occurred when parsing tile data from a csv encoded dataset.
TileDataParseError(ParseIntError),
}
impl fmt::Display for CsvDecodingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CsvDecodingError::TileDataParseError(e) => write!(f, "{}", e),
}
}
}
impl std::error::Error for CsvDecodingError {}
/// Errors that can occur parsing a Tileset.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum InvalidTilesetError {
/// An invalid width or height (0) dimension was found in the input.
InvalidTileDimensions,
}
impl fmt::Display for InvalidTilesetError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
InvalidTileDimensions => write!(
f,
"An invalid width or height (0) dimension was found in the input."
),
}
}
}
impl std::error::Error for InvalidTilesetError {}
/// Errors which occurred when parsing the file
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
/// A attribute was missing, had the wrong type of wasn't formated
/// correctly.
MalformedAttributes(String),
/// An error occurred when decompressing using the
/// [flate2](https://github.com/alexcrichton/flate2-rs) crate.
DecompressingError(std::io::Error),
/// An error occurred when decoding a base64 encoded dataset.
Base64DecodingError(base64::DecodeError),
/// An error occurred when decoding a csv encoded dataset.
CsvDecodingError(CsvDecodingError),
/// An error occurred when parsing an XML file, such as a TMX or TSX file.
XmlDecodingError(xml::reader::Error),
#[cfg(feature = "world")]
/// An error occurred when attempting to deserialize a JSON file.
JsonDecodingError(serde_json::Error),
#[cfg(feature = "world")]
/// Filename does not match any pattern in the world file.
NoMatchFound {
/// The filename that was not matched.
path: String,
},
/// A parameter is out of range or results in arithmetic underflow or overflow.
RangeError(String),
/// The XML stream ended before the document was fully parsed.
PrematureEnd(String),
/// The path given is invalid because it isn't contained in any folder.
PathIsNotFile,
/// An error generated by [`ResourceReader`](crate::ResourceReader) while trying to read a
/// resource.
ResourceLoadingError {
/// The path to the file that was unable to be opened.
path: PathBuf,
/// The error that occurred when trying to open the file.
err: Box<dyn std::error::Error + Send + Sync + 'static>,
},
/// There was an invalid tile in the map parsed.
InvalidTileFound,
/// Unknown encoding or compression format or invalid combination of both (for tile layers)
InvalidEncodingFormat {
/// The `encoding` attribute of the tile layer data, if any.
encoding: Option<String>,
/// The `compression` attribute of the tile layer data, if any.
compression: Option<String>,
},
/// There was an error parsing the value of a [`PropertyValue`].
///
/// [`PropertyValue`]: crate::PropertyValue
InvalidPropertyValue {
/// A description of the error that occurred.
description: String,
},
/// Found an unknown property value type while parsing a [`PropertyValue`].
///
/// [`PropertyValue`]: crate::PropertyValue
UnknownPropertyType {
/// The name of the type that isn't recognized by the crate.
/// Supported types are `string`, `int`, `float`, `bool`, `color`, `file` and `object`.
type_name: String,
},
/// A template was found that does not have an object element in it.
TemplateHasNoObject,
/// Found a WangId that was not properly formatted.
InvalidWangIdEncoding {
/// Stores the wrongly parsed String.
read_string: String,
},
/// There was an error parsing an Object's data.
InvalidObjectData {
/// A description of the error that occurred.
description: String,
},
/// There was an invalid tileset in the map parsed.
InvalidTileset(InvalidTilesetError),
}
/// A result with an error variant of [`crate::Error`].
pub type Result<T> = std::result::Result<T, Error>;
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
match self {
Error::MalformedAttributes(s) => write!(fmt, "{}", s),
Error::DecompressingError(e) => write!(fmt, "{}", e),
Error::Base64DecodingError(e) => write!(fmt, "{}", e),
Error::CsvDecodingError(e) => write!(fmt, "{}", e),
Error::XmlDecodingError(e) => write!(fmt, "{}", e),
#[cfg(feature = "world")]
Error::JsonDecodingError(e) => write!(fmt, "{}", e),
#[cfg(feature = "world")]
Error::NoMatchFound { path } => {
write!(fmt, "No match found for path: '{}'", path)
}
Error::RangeError(e) => write!(fmt, "Range error: {}", e),
Error::PrematureEnd(e) => write!(fmt, "{}", e),
Error::PathIsNotFile => {
write!(
fmt,
"The path given is invalid because it isn't contained in any folder."
)
}
Error::ResourceLoadingError { path, err } => {
write!(
fmt,
"Could not open '{}'. Error: {}",
path.to_string_lossy(),
err
)
}
Error::InvalidTileFound => write!(fmt, "Invalid tile found in map being parsed"),
Error::InvalidEncodingFormat { encoding: None, compression: None } =>
write!(
fmt,
"Deprecated combination of encoding and compression"
),
Error::InvalidEncodingFormat { encoding, compression } =>
write!(
fmt,
"Unknown encoding or compression format or invalid combination of both (for tile layers): {} encoding with {} compression",
encoding.as_deref().unwrap_or("no"),
compression.as_deref().unwrap_or("no")
),
Error::InvalidPropertyValue{description} =>
write!(fmt, "Invalid property value: {}", description),
Error::UnknownPropertyType { type_name } =>
write!(fmt, "Unknown property value type '{}'", type_name),
Error::TemplateHasNoObject => write!(fmt, "A template was found with no object element"),
Error::InvalidWangIdEncoding{read_string} =>
write!(fmt, "\"{}\" is not a valid WangId format", read_string),
Error::InvalidObjectData{description} =>
write!(fmt, "Invalid object data: {}", description),
Error::InvalidTileset(e) => write!(fmt, "{}", e),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::DecompressingError(e) => Some(e as &dyn std::error::Error),
Error::Base64DecodingError(e) => Some(e as &dyn std::error::Error),
Error::XmlDecodingError(e) => Some(e as &dyn std::error::Error),
Error::ResourceLoadingError { err, .. } => Some(err.as_ref()),
_ => None,
}
}
}