summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLawnCable <git@lawncable.net>2022-04-15 08:37:07 +0200
committerLawnCable <git@lawncable.net>2022-04-15 08:37:07 +0200
commit6077ff47af622503d990772607e514d109799169 (patch)
tree10fc04533444897ea1950601bd4031ed43b4b0a1 /src
parentbbeb30c9817327f8c6fc7e50580f3e5f567dfafe (diff)
downloadfast-tiled.rs-6077ff47af622503d990772607e514d109799169.tar.gz
fast-tiled.rs-6077ff47af622503d990772607e514d109799169.tar.bz2
fast-tiled.rs-6077ff47af622503d990772607e514d109799169.tar.xz
fast-tiled.rs-6077ff47af622503d990772607e514d109799169.zip
make name, tile_count and columns optional so it does not fail parsing older/invalid maps
also add the log crate to still print warnings in these cases
Diffstat (limited to 'src')
-rw-r--r--src/lowlevel/macros.rs15
-rw-r--r--src/lowlevel/tileset.rs69
2 files changed, 52 insertions, 32 deletions
diff --git a/src/lowlevel/macros.rs b/src/lowlevel/macros.rs
index 29c4511..b14ae13 100644
--- a/src/lowlevel/macros.rs
+++ b/src/lowlevel/macros.rs
@@ -18,6 +18,21 @@ macro_rules! get_attribute {
}
#[macro_export]
+macro_rules! get_recommended_attribute {
+ ($node:expr, $attribute_name:expr) => {{
+ let node: &roxmltree::Node = &$node;
+ let attribute_name: &str = $attribute_name;
+ match node.attribute(attribute_name) {
+ None => {
+ warn!("{} attribute missing", attribute_name);
+ None
+ }
+ Some(v) => Some(v.to_owned()),
+ }
+ }};
+}
+
+#[macro_export]
macro_rules! ensure_element {
($node:expr) => {
if $node.node_type() != roxmltree::NodeType::Element {
diff --git a/src/lowlevel/tileset.rs b/src/lowlevel/tileset.rs
index 5a13cba..5804138 100644
--- a/src/lowlevel/tileset.rs
+++ b/src/lowlevel/tileset.rs
@@ -1,5 +1,6 @@
-use crate::{ensure_element, ensure_tag_name, get_attribute};
-use anyhow::{anyhow, bail, Context};
+use crate::{ensure_element, ensure_tag_name, get_attribute, get_recommended_attribute};
+use anyhow::{anyhow, Context};
+use log::warn;
use super::image::Image;
use super::property::Properties;
@@ -541,7 +542,7 @@ pub struct TileSet {
pub version: Option<String>,
/// The name of this tileset.
- pub name: String,
+ pub name: Option<String>,
/// The (maximum) width of the tiles in this tileset.
pub tile_width: usize,
@@ -554,11 +555,11 @@ pub struct TileSet {
pub margin: usize,
/// The number of tiles in this tileset (since 0.13)
- pub tile_count: usize,
+ pub tile_count: Option<usize>,
/// The number of tile columns in the tileset.
/// For image collection tilesets it is editable and is used when displaying the tileset. (since 0.15)
- pub columns: usize,
+ pub columns: Option<usize>,
/// Controls the alignment for tile objects.
/// Valid values are unspecified, topleft, top, topright, left, center, right, bottomleft, bottom and bottomright.
@@ -672,69 +673,73 @@ impl TileSet {
let tile_width = get_attribute!(node, "tilewidth")?.parse()?;
let tile_height = get_attribute!(node, "tileheight")?.parse()?;
- let tile_count: usize = match get_attribute!(node, "tilecount") {
- Ok(tc_string) => tc_string.parse()?,
+ let tile_count: Option<usize> = match get_attribute!(node, "tilecount") {
+ Ok(tc_string) => Some(tc_string.parse()?),
Err(err) => {
if let Some(img) = &image {
// there is no tilecount, but an image so we can guess/calculate the tilecount
// TODO TEST for this
if spacing != 0 {
- bail!("tilecount not set, and calculationg it with spacing enabled is not implemented yet.");
- }
-
- if let Some(image_width) = img.width {
+ warn!("tilecount not set, and calculationg it with spacing enabled is not implemented yet.");
+ None
+ } else if let Some(image_width) = img.width {
if let Some(image_heigth) = img.height {
let real_tile_with = tile_width + (margin * 2);
let real_tile_height = tile_height + (margin * 2);
let columns = image_width / real_tile_with;
let rows = image_heigth / real_tile_height;
- columns * rows
+ Some(columns * rows)
} else {
- bail!("tilecount not set, calculating failed: image has no height");
+ warn!("tilecount not set, calculating failed: image has no height");
+ None
}
} else {
- bail!("tilecount not set, calculating failed: image has no width");
+ warn!("tilecount not set, calculating failed: image has no width");
+ None
}
} else {
- return Err(err);
+ warn!("tilecount not set, calculating failed: no image");
+ None
}
}
};
- let columns: usize = match get_attribute!(node, "columns") {
- Ok(c) => c.parse()?,
+ let columns: Option<usize> = match get_attribute!(node, "columns") {
+ Ok(c) => Some(c.parse()?),
Err(err) => {
if let Some(img) = &image {
// there is no columns attribute, but an image so we can guess/calculate the columns
// TODO TEST for this
if spacing != 0 {
- bail!("columns not set, and calculationg it with spacing enabled is not implemented yet.");
- }
-
- if let Some(image_width) = img.width {
+ warn!("columns not set, and calculationg it with spacing enabled is not implemented yet.");
+ None
+ } else if let Some(image_width) = img.width {
if let Some(image_heigth) = img.height {
let real_tile_with = tile_width + (margin * 2);
let real_tile_height = tile_height + (margin * 2);
let columns = image_width / real_tile_with;
let rows = image_heigth / real_tile_height;
- columns * rows
+ Some(columns * rows)
} else {
- bail!("columns not set, calculating failed: image has no height");
+ warn!("columns not set, calculating failed: image has no height");
+ None
}
} else {
- bail!("columns not set, calculating failed: image has no width");
+ warn!("columns not set, calculating failed: image has no width");
+ None
}
} else {
- return Err(err);
+ warn!("columns not set, calculating failed: image has no width");
+ None
}
}
};
Ok(TileSet {
version,
- name: get_attribute!(node, "name")?.to_owned(),
+ name: get_recommended_attribute!(node, "name"),
tile_width,
tile_height,
spacing,
@@ -770,13 +775,13 @@ mod test_tileset {
tile_set,
TileSet {
version: None,
- name: "beach_tileset".to_owned(),
+ name: Some("beach_tileset".to_owned()),
tile_width: 16,
tile_height: 16,
spacing: 0,
margin: 0,
- tile_count: 936,
- columns: 36,
+ tile_count: Some(936),
+ columns: Some(36),
object_alignment: ObjectAlignment::Unspecified,
tile: vec![
Tile {
@@ -894,7 +899,7 @@ mod test_tileset_element {
first_gid: 1,
tileset: TileSet {
version: None,
- name: "hex mini".to_owned(),
+ name: Some("hex mini".to_owned()),
tile_width: 18,
tile_height: 18,
tile_offset: TileOffset { x: 0, y: 1 },
@@ -902,8 +907,8 @@ mod test_tileset_element {
wangsets: vec![],
spacing: 0,
margin: 0,
- tile_count: 20,
- columns: 5,
+ tile_count: Some(20),
+ columns: Some(5),
object_alignment: ObjectAlignment::default(),
tile: vec![],
image: Some(Image {