summaryrefslogtreecommitdiff
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
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
-rw-r--r--Cargo.lock53
-rw-r--r--Cargo.toml3
-rw-r--r--src/lowlevel/macros.rs15
-rw-r--r--src/lowlevel/tileset.rs69
4 files changed, 54 insertions, 86 deletions
diff --git a/Cargo.lock b/Cargo.lock
deleted file mode 100644
index 3df5c0d..0000000
--- a/Cargo.lock
+++ /dev/null
@@ -1,53 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "anyhow"
-version = "1.0.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
-
-[[package]]
-name = "bytemuck"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
-
-[[package]]
-name = "fast-tiled"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "read_color",
- "rgb",
- "roxmltree",
-]
-
-[[package]]
-name = "read_color"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f4c8858baa4ad3c8bcc156ae91a0ffe22b76a3975c40c49b4f04c15c6bce0da"
-
-[[package]]
-name = "rgb"
-version = "0.8.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fddb3b23626145d1776addfc307e1a1851f60ef6ca64f376bcb889697144cf0"
-dependencies = [
- "bytemuck",
-]
-
-[[package]]
-name = "roxmltree"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b"
-dependencies = [
- "xmlparser",
-]
-
-[[package]]
-name = "xmlparser"
-version = "0.13.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8"
diff --git a/Cargo.toml b/Cargo.toml
index f4267e6..62a0304 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,4 +10,5 @@ edition = "2018"
anyhow = "1.0.40"
rgb = "0.8.27"
roxmltree = "0.14.1"
-read_color = "1.0.0" \ No newline at end of file
+read_color = "1.0.0"
+log = "0.4.16"
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 {