From 2e4ac19cc95f086fda4bed992ad55614c9fd1459 Mon Sep 17 00:00:00 2001 From: Frizi <frizi09@gmail.com> Date: Tue, 18 Dec 2018 19:11:34 +0100 Subject: [PATCH] Rustfmt pass and slight macro stylistic changes --- examples/main.rs | 2 +- src/lib.rs | 817 +++++++++++++++++++++++++++++------------------ 2 files changed, 500 insertions(+), 319 deletions(-) diff --git a/examples/main.rs b/examples/main.rs index 4835e55..202fbf7 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -1,7 +1,7 @@ extern crate tiled; -use std::path::Path; use std::fs::File; +use std::path::Path; use tiled::parse; fn main() { diff --git a/src/lib.rs b/src/lib.rs index bc1143d..96f5e02 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,16 @@ +extern crate base64; extern crate libflate; extern crate xml; -extern crate base64; -use std::str::FromStr; use std::collections::HashMap; +use std::fmt; use std::fs::File; -use std::io::{BufReader, Read, Error}; +use std::io::{BufReader, Error, Read}; use std::path::Path; -use std::fmt; -use xml::reader::{EventReader, Error as XmlError}; -use xml::reader::XmlEvent; +use std::str::FromStr; use xml::attribute::OwnedAttribute; +use xml::reader::XmlEvent; +use xml::reader::{Error as XmlError, EventReader}; #[derive(Debug, Copy, Clone)] pub enum ParseTileError { @@ -25,8 +25,8 @@ pub enum ParseTileError { // This is probably a really terrible way to do this. It does cut down on lines // though which is nice. macro_rules! get_attrs { - ($attrs:expr, optionals: [$(($oName:pat, $oVar:ident, $oMethod:expr)),*], - required: [$(($name:pat, $var:ident, $method:expr)),*], $err:expr) => { + ($attrs:expr, optionals: [$(($oName:pat, $oVar:ident, $oMethod:expr)),* $(,)*], + required: [$(($name:pat, $var:ident, $method:expr)),* $(,)*], $err:expr) => { { $(let mut $oVar = None;)* $(let mut $var = None;)* @@ -50,7 +50,7 @@ macro_rules! get_attrs { // // Not quite as bad. macro_rules! parse_tag { - ($parser:expr, $close_tag:expr, $($open_tag:expr => $open_method:expr),*) => { + ($parser:expr, $close_tag:expr, {$($open_tag:expr => $open_method:expr),* $(,)*}) => { loop { match try!($parser.next().map_err(TiledError::XmlDecodingError)) { XmlEvent::StartElement {name, attributes, ..} => { @@ -78,18 +78,14 @@ macro_rules! parse_tag { pub struct Colour { pub red: u8, pub green: u8, - pub blue: u8 + pub blue: u8, } impl FromStr for Colour { type Err = ParseTileError; fn from_str(s: &str) -> Result<Colour, ParseTileError> { - let s = if s.starts_with("#") { - &s[1..] - } else { - s - }; + let s = if s.starts_with("#") { &s[1..] } else { s }; if s.len() != 6 { return Err(ParseTileError::ColourError); } @@ -97,7 +93,11 @@ impl FromStr for Colour { let g = u8::from_str_radix(&s[2..4], 16); let b = u8::from_str_radix(&s[4..6], 16); if r.is_ok() && g.is_ok() && b.is_ok() { - return Ok(Colour {red: r.unwrap(), green: g.unwrap(), blue: b.unwrap()}) + return Ok(Colour { + red: r.unwrap(), + green: g.unwrap(), + blue: b.unwrap(), + }); } Err(ParseTileError::ColourError) } @@ -115,7 +115,7 @@ pub enum TiledError { Base64DecodingError(base64::DecodeError), XmlDecodingError(XmlError), PrematureEnd(String), - Other(String) + Other(String), } impl fmt::Display for TiledError { @@ -153,7 +153,6 @@ impl std::error::Error for TiledError { TiledError::Other(_) => None, } } - } #[derive(Debug, PartialEq, Clone)] @@ -185,10 +184,15 @@ impl PropertyValue { }, "color" if value.len() > 1 => match u32::from_str_radix(&value[1..], 16) { Ok(color) => Ok(PropertyValue::ColorValue(color)), - Err(_) => Err(TiledError::Other(format!("Improperly formatted color property"))), + Err(_) => Err(TiledError::Other(format!( + "Improperly formatted color property" + ))), }, "string" => Ok(PropertyValue::StringValue(value)), - _ => Err(TiledError::Other(format!("Unknown property type \"{}\"", property_type))), + _ => Err(TiledError::Other(format!( + "Unknown property type \"{}\"", + property_type + ))), } } } @@ -197,21 +201,25 @@ pub type Properties = HashMap<String, PropertyValue>; fn parse_properties<R: Read>(parser: &mut EventReader<R>) -> Result<Properties, TiledError> { let mut p = HashMap::new(); - parse_tag!( - parser, "properties", + parse_tag!(parser, "properties", { "property" => |attrs:Vec<OwnedAttribute>| { - let (t, (k, v)) = get_attrs!( - attrs, - optionals: [("type", property_type, |v| Some(v))], - required: [("name", key, |v| Some(v)), - ("value", value, |v| Some(v))], - TiledError::MalformedAttributes("property must have a name and a value".to_string())); - let t = t.unwrap_or("string".into()); - - p.insert(k, try!(PropertyValue::new(t, v))); - Ok(()) - } - ); + let (t, (k, v)) = get_attrs!( + attrs, + optionals: [ + ("type", property_type, |v| Some(v)), + ], + required: [ + ("name", key, |v| Some(v)), + ("value", value, |v| Some(v)), + ], + TiledError::MalformedAttributes("property must have a name and a value".to_string()) + ); + let t = t.unwrap_or("string".into()); + + p.insert(k, try!(PropertyValue::new(t, v))); + Ok(()) + }, + }); Ok(p) } @@ -233,17 +241,26 @@ pub struct Map { } impl Map { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, map_path: Option<&Path>) -> Result<Map, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + map_path: Option<&Path>, + ) -> Result<Map, TiledError> { let (c, (v, o, w, h, tw, th)) = get_attrs!( attrs, - optionals: [("backgroundcolor", colour, |v:String| v.parse().ok())], - required: [("version", version, |v| Some(v)), - ("orientation", orientation, |v:String| v.parse().ok()), - ("width", width, |v:String| v.parse().ok()), - ("height", height, |v:String| v.parse().ok()), - ("tilewidth", tile_width, |v:String| v.parse().ok()), - ("tileheight", tile_height, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("map must have a version, width and height with correct types".to_string())); + optionals: [ + ("backgroundcolor", colour, |v:String| v.parse().ok()), + ], + required: [ + ("version", version, |v| Some(v)), + ("orientation", orientation, |v:String| v.parse().ok()), + ("width", width, |v:String| v.parse().ok()), + ("height", height, |v:String| v.parse().ok()), + ("tilewidth", tile_width, |v:String| v.parse().ok()), + ("tileheight", tile_height, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("map must have a version, width and height with correct types".to_string()) + ); let mut tilesets = Vec::new(); let mut layers = Vec::new(); @@ -251,39 +268,45 @@ impl Map { let mut properties = HashMap::new(); let mut object_groups = Vec::new(); let mut layer_index = 0; - parse_tag!(parser, "map", - "tileset" => | attrs| { - tilesets.push(try!(Tileset::new(parser, attrs, map_path))); - Ok(()) - }, - "layer" => |attrs| { - layers.push(try!(Layer::new(parser, attrs, w, layer_index))); - layer_index += 1; - Ok(()) - }, - "imagelayer" => |attrs| { - image_layers.push(try!(ImageLayer::new(parser, attrs, layer_index))); - layer_index += 1; - Ok(()) - }, - "properties" => |_| { - properties = try!(parse_properties(parser)); - Ok(()) - }, - "objectgroup" => |attrs| { - object_groups.push(try!(ObjectGroup::new(parser, attrs, Some(layer_index)))); - layer_index += 1; - Ok(()) - }); - Ok(Map {version: v, orientation: o, - width: w, height: h, - tile_width: tw, tile_height: th, - tilesets, - layers, - image_layers, - object_groups, - properties, - background_colour: c,}) + parse_tag!(parser, "map", { + "tileset" => | attrs| { + tilesets.push(try!(Tileset::new(parser, attrs, map_path))); + Ok(()) + }, + "layer" => |attrs| { + layers.push(try!(Layer::new(parser, attrs, w, layer_index))); + layer_index += 1; + Ok(()) + }, + "imagelayer" => |attrs| { + image_layers.push(try!(ImageLayer::new(parser, attrs, layer_index))); + layer_index += 1; + Ok(()) + }, + "properties" => |_| { + properties = try!(parse_properties(parser)); + Ok(()) + }, + "objectgroup" => |attrs| { + object_groups.push(try!(ObjectGroup::new(parser, attrs, Some(layer_index)))); + layer_index += 1; + Ok(()) + }, + }); + Ok(Map { + version: v, + orientation: o, + width: w, + height: h, + tile_width: tw, + tile_height: th, + tilesets, + layers, + image_layers, + object_groups, + properties, + background_colour: c, + }) } /// This function will return the correct Tileset given a GID. @@ -305,7 +328,7 @@ pub enum Orientation { Orthogonal, Isometric, Staggered, - Hexagonal + Hexagonal, } impl FromStr for Orientation { @@ -317,7 +340,7 @@ impl FromStr for Orientation { "isometric" => Ok(Orientation::Isometric), "staggered" => Ok(Orientation::Staggered), "hexagonal" => Ok(Orientation::Hexagonal), - _ => Err(ParseTileError::OrientationError) + _ => Err(ParseTileError::OrientationError), } } } @@ -335,57 +358,83 @@ pub struct Tileset { /// The Tiled spec says that a tileset can have mutliple images so a `Vec` /// is used. Usually you will only use one. pub images: Vec<Image>, - pub tiles: Vec<Tile> + pub tiles: Vec<Tile>, } impl Tileset { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, map_path: Option<&Path>) -> Result<Tileset, TiledError> { - Tileset::new_internal(parser, &attrs) - .or_else(|_| { Tileset::new_reference(&attrs, map_path) }) + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + map_path: Option<&Path>, + ) -> Result<Tileset, TiledError> { + Tileset::new_internal(parser, &attrs).or_else(|_| Tileset::new_reference(&attrs, map_path)) } - fn new_internal<R: Read>(parser: &mut EventReader<R>, attrs: &Vec<OwnedAttribute>) -> Result<Tileset, TiledError> { + fn new_internal<R: Read>( + parser: &mut EventReader<R>, + attrs: &Vec<OwnedAttribute>, + ) -> Result<Tileset, TiledError> { let ((spacing, margin), (first_gid, name, width, height)) = get_attrs!( attrs, - optionals: [("spacing", spacing, |v:String| v.parse().ok()), - ("margin", margin, |v:String| v.parse().ok())], - required: [("firstgid", first_gid, |v:String| v.parse().ok()), - ("name", name, |v| Some(v)), - ("tilewidth", width, |v:String| v.parse().ok()), - ("tileheight", height, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())); + optionals: [ + ("spacing", spacing, |v:String| v.parse().ok()), + ("margin", margin, |v:String| v.parse().ok()), + ], + required: [ + ("firstgid", first_gid, |v:String| v.parse().ok()), + ("name", name, |v| Some(v)), + ("tilewidth", width, |v:String| v.parse().ok()), + ("tileheight", height, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string()) + ); let mut images = Vec::new(); let mut tiles = Vec::new(); - parse_tag!(parser, "tileset", - "image" => |attrs| { - images.push(try!(Image::new(parser, attrs))); - Ok(()) - }, - "tile" => |attrs| { - tiles.push(try!(Tile::new(parser, attrs))); - Ok(()) - }); - - Ok(Tileset {first_gid: first_gid, - name: name, - tile_width: width, tile_height: height, - spacing: spacing.unwrap_or(0), - margin: margin.unwrap_or(0), - images: images, - tiles: tiles}) + parse_tag!(parser, "tileset", { + "image" => |attrs| { + images.push(try!(Image::new(parser, attrs))); + Ok(()) + }, + "tile" => |attrs| { + tiles.push(try!(Tile::new(parser, attrs))); + Ok(()) + }, + }); + + Ok(Tileset { + first_gid: first_gid, + name: name, + tile_width: width, + tile_height: height, + spacing: spacing.unwrap_or(0), + margin: margin.unwrap_or(0), + images: images, + tiles: tiles, + }) } - fn new_reference(attrs: &Vec<OwnedAttribute>, map_path: Option<&Path>) -> Result<Tileset, TiledError> { + fn new_reference( + attrs: &Vec<OwnedAttribute>, + map_path: Option<&Path>, + ) -> Result<Tileset, TiledError> { let ((), (first_gid, source)) = get_attrs!( - attrs, - optionals: [], - required: [("firstgid", first_gid, |v:String| v.parse().ok()), - ("source", name, |v| Some(v))], - TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())); + attrs, + optionals: [], + required: [ + ("firstgid", first_gid, |v:String| v.parse().ok()), + ("source", name, |v| Some(v)), + ], + TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string()) + ); let tileset_path = map_path.ok_or(TiledError::Other("Maps with external tilesets must know their file location. See parse_with_path(Path).".to_string()))?.with_file_name(source); - let file = File::open(&tileset_path).map_err(|_| TiledError::Other(format!("External tileset file not found: {:?}", tileset_path)))?; + let file = File::open(&tileset_path).map_err(|_| { + TiledError::Other(format!( + "External tileset file not found: {:?}", + tileset_path + )) + })?; Tileset::new_external(file, first_gid) } @@ -393,46 +442,69 @@ impl Tileset { let mut tileset_parser = EventReader::new(file); loop { match try!(tileset_parser.next().map_err(TiledError::XmlDecodingError)) { - XmlEvent::StartElement {name, attributes, ..} => { + XmlEvent::StartElement { + name, attributes, .. + } => { if name.local_name == "tileset" { - return Tileset::parse_external_tileset(first_gid, &mut tileset_parser, &attributes) + return Tileset::parse_external_tileset( + first_gid, + &mut tileset_parser, + &attributes, + ); } } - XmlEvent::EndDocument => return Err(TiledError::PrematureEnd("Tileset Document ended before map was parsed".to_string())), + XmlEvent::EndDocument => { + return Err(TiledError::PrematureEnd( + "Tileset Document ended before map was parsed".to_string(), + )) + } _ => {} } } } - fn parse_external_tileset<R: Read>(first_gid: u32, parser: &mut EventReader<R>, attrs: &Vec<OwnedAttribute>) -> Result<Tileset, TiledError> { + fn parse_external_tileset<R: Read>( + first_gid: u32, + parser: &mut EventReader<R>, + attrs: &Vec<OwnedAttribute>, + ) -> Result<Tileset, TiledError> { let ((spacing, margin), (name, width, height)) = get_attrs!( attrs, - optionals: [("spacing", spacing, |v:String| v.parse().ok()), - ("margin", margin, |v:String| v.parse().ok())], - required: [("name", name, |v| Some(v)), - ("tilewidth", width, |v:String| v.parse().ok()), - ("tileheight", height, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())); + optionals: [ + ("spacing", spacing, |v:String| v.parse().ok()), + ("margin", margin, |v:String| v.parse().ok()), + ], + required: [ + ("name", name, |v| Some(v)), + ("tilewidth", width, |v:String| v.parse().ok()), + ("tileheight", height, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string()) + ); let mut images = Vec::new(); let mut tiles = Vec::new(); - parse_tag!(parser, "tileset", - "image" => |attrs| { - images.push(try!(Image::new(parser, attrs))); - Ok(()) - }, - "tile" => |attrs| { - tiles.push(try!(Tile::new(parser, attrs))); - Ok(()) - }); - - Ok(Tileset {first_gid: first_gid, - name: name, - tile_width: width, tile_height: height, - spacing: spacing.unwrap_or(0), - margin: margin.unwrap_or(0), - images: images, - tiles: tiles}) + parse_tag!(parser, "tileset", { + "image" => |attrs| { + images.push(try!(Image::new(parser, attrs))); + Ok(()) + }, + "tile" => |attrs| { + tiles.push(try!(Tile::new(parser, attrs))); + Ok(()) + }, + }); + + Ok(Tileset { + first_gid: first_gid, + name: name, + tile_width: width, + tile_height: height, + spacing: spacing.unwrap_or(0), + margin: margin.unwrap_or(0), + images: images, + tiles: tiles, + }) } } @@ -452,19 +524,26 @@ pub struct Tile { const FLIPPED_HORIZONTALLY_FLAG: u32 = 0x8; const FLIPPED_VERTICALLY_FLAG: u32 = 0x4; const FLIPPED_DIAGONALLY_FLAG: u32 = 0x2; -const ALL_FLIP_FLAGS: u32 = FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG; +const ALL_FLIP_FLAGS: u32 = + FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG; impl Tile { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Result<Tile, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + ) -> Result<Tile, TiledError> { let ((tile_type, probability), id) = get_attrs!( attrs, optionals: [ ("type", tile_type, |v:String| v.parse().ok()), - ("probability", probability, |v:String| v.parse().ok()) + ("probability", probability, |v:String| v.parse().ok()), ], - required: [("id", id, |v:String| v.parse::<u32>().ok())], - TiledError::MalformedAttributes("tile must have an id with the correct type".to_string())); - + required: [ + ("id", id, |v:String| v.parse::<u32>().ok()), + ], + TiledError::MalformedAttributes("tile must have an id with the correct type".to_string()) + ); + let flags = (id & ALL_FLIP_FLAGS) >> 28; let id: u32 = id & !ALL_FLIP_FLAGS; let diagon = flags & FLIPPED_DIAGONALLY_FLAG == FLIPPED_DIAGONALLY_FLAG; @@ -475,24 +554,35 @@ impl Tile { let mut properties = HashMap::new(); let mut objectgroup = None; let mut animation = None; - parse_tag!(parser, "tile", - "image" => |attrs| { - images.push(Image::new(parser, attrs)?); - Ok(()) - }, - "properties" => |_| { - properties = parse_properties(parser)?; - Ok(()) - }, - "objectgroup" => |attrs| { - objectgroup = Some(ObjectGroup::new(parser, attrs, None)?); - Ok(()) - }, - "animation" => |_| { - animation = Some(parse_animation(parser)?); - Ok(()) - }); - Ok(Tile {id, flip_h, flip_v, images, properties, objectgroup, animation, tile_type, probability: probability.unwrap_or(1.0)}) + parse_tag!(parser, "tile", { + "image" => |attrs| { + images.push(Image::new(parser, attrs)?); + Ok(()) + }, + "properties" => |_| { + properties = parse_properties(parser)?; + Ok(()) + }, + "objectgroup" => |attrs| { + objectgroup = Some(ObjectGroup::new(parser, attrs, None)?); + Ok(()) + }, + "animation" => |_| { + animation = Some(parse_animation(parser)?); + Ok(()) + }, + }); + Ok(Tile { + id, + flip_h, + flip_v, + images, + properties, + objectgroup, + animation, + tile_type, + probability: probability.unwrap_or(1.0), + }) } } @@ -506,17 +596,30 @@ pub struct Image { } impl Image { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Result<Image, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + ) -> Result<Image, TiledError> { let (c, (s, w, h)) = get_attrs!( attrs, - optionals: [("trans", trans, |v:String| v.parse().ok())], - required: [("source", source, |v| Some(v)), - ("width", width, |v:String| v.parse().ok()), - ("height", height, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("image must have a source, width and height with correct types".to_string())); - - parse_tag!(parser, "image", "" => |_| Ok(())); - Ok(Image {source: s, width: w, height: h, transparent_colour: c}) + optionals: [ + ("trans", trans, |v:String| v.parse().ok()), + ], + required: [ + ("source", source, |v| Some(v)), + ("width", width, |v:String| v.parse().ok()), + ("height", height, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("image must have a source, width and height with correct types".to_string()) + ); + + parse_tag!(parser, "image", { "" => |_| Ok(()) }); + Ok(Image { + source: s, + width: w, + height: h, + transparent_colour: c, + }) } } @@ -533,26 +636,44 @@ pub struct Layer { } impl Layer { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, width: u32, layer_index: u32) -> Result<Layer, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + width: u32, + layer_index: u32, + ) -> Result<Layer, TiledError> { let ((o, v), n) = get_attrs!( attrs, - optionals: [("opacity", opacity, |v:String| v.parse().ok()), - ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1))], - required: [("name", name, |v| Some(v))], - TiledError::MalformedAttributes("layer must have a name".to_string())); + optionals: [ + ("opacity", opacity, |v:String| v.parse().ok()), + ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), + ], + required: [ + ("name", name, |v| Some(v)), + ], + TiledError::MalformedAttributes("layer must have a name".to_string()) + ); let mut tiles = Vec::new(); let mut properties = HashMap::new(); - parse_tag!(parser, "layer", - "data" => |attrs| { - tiles = try!(parse_data(parser, attrs, width)); - Ok(()) - }, - "properties" => |_| { - properties = try!(parse_properties(parser)); - Ok(()) - }); - Ok(Layer {name: n, opacity: o.unwrap_or(1.0), visible: v.unwrap_or(true), tiles: tiles, - properties: properties, layer_index}) + parse_tag!(parser, "layer", { + "data" => |attrs| { + tiles = try!(parse_data(parser, attrs, width)); + Ok(()) + }, + "properties" => |_| { + properties = try!(parse_properties(parser)); + Ok(()) + }, + }); + + Ok(Layer { + name: n, + opacity: o.unwrap_or(1.0), + visible: v.unwrap_or(true), + tiles: tiles, + properties: properties, + layer_index, + }) } } @@ -569,27 +690,35 @@ pub struct ImageLayer { } impl ImageLayer { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, layer_index: u32) - -> Result<ImageLayer, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + layer_index: u32, + ) -> Result<ImageLayer, TiledError> { let ((o, v, ox, oy), n) = get_attrs!( attrs, - optionals: [("opacity", opacity, |v:String| v.parse().ok()), - ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), - ("offsetx", offset_x, |v:String| v.parse().ok()), - ("offsety", offset_y, |v:String| v.parse().ok())], - required: [("name", name, |v| Some(v))], + optionals: [ + ("opacity", opacity, |v:String| v.parse().ok()), + ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), + ("offsetx", offset_x, |v:String| v.parse().ok()), + ("offsety", offset_y, |v:String| v.parse().ok()), + ], + required: [ + ("name", name, |v| Some(v)), + ], TiledError::MalformedAttributes("layer must have a name".to_string())); let mut properties = HashMap::new(); let mut image: Option<Image> = None; - parse_tag!(parser, "imagelayer", - "image" => |attrs| { - image = Some(Image::new(parser, attrs)?); - Ok(()) - }, - "properties" => |_| { - properties = parse_properties(parser)?; - Ok(()) - }); + parse_tag!(parser, "imagelayer", { + "image" => |attrs| { + image = Some(Image::new(parser, attrs)?); + Ok(()) + }, + "properties" => |_| { + properties = parse_properties(parser)?; + Ok(()) + }, + }); Ok(ImageLayer { name: n, opacity: o.unwrap_or(1.0), @@ -603,8 +732,6 @@ impl ImageLayer { } } - - #[derive(Debug, PartialEq, Clone)] pub struct ObjectGroup { pub name: String, @@ -619,45 +746,46 @@ pub struct ObjectGroup { } impl ObjectGroup { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, layer_index: Option<u32>) -> Result<ObjectGroup, TiledError> { + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + layer_index: Option<u32>, + ) -> Result<ObjectGroup, TiledError> { let ((o, v, c, n), ()) = get_attrs!( attrs, - optionals: [("opacity", opacity, |v:String| v.parse().ok()), - ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), - ("color", colour, |v:String| v.parse().ok()), - ("name", name, |v:String| v.into())], + optionals: [ + ("opacity", opacity, |v:String| v.parse().ok()), + ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), + ("color", colour, |v:String| v.parse().ok()), + ("name", name, |v:String| v.into()), + ], required: [], - TiledError::MalformedAttributes("object groups must have a name".to_string())); + TiledError::MalformedAttributes("object groups must have a name".to_string()) + ); let mut objects = Vec::new(); - parse_tag!(parser, "objectgroup", - "object" => |attrs| { - objects.push(try!(Object::new(parser, attrs))); - Ok(()) - }); - Ok(ObjectGroup {name: n.unwrap_or(String::new()), - opacity: o.unwrap_or(1.0), visible: v.unwrap_or(true), - objects: objects, - colour: c, - layer_index}) + parse_tag!(parser, "objectgroup", { + "object" => |attrs| { + objects.push(try!(Object::new(parser, attrs))); + Ok(()) + }, + }); + Ok(ObjectGroup { + name: n.unwrap_or(String::new()), + opacity: o.unwrap_or(1.0), + visible: v.unwrap_or(true), + objects: objects, + colour: c, + layer_index, + }) } } #[derive(Debug, PartialEq, Clone)] pub enum ObjectShape { - Rect { - width: f32, - height: f32, - }, - Ellipse { - width: f32, - height: f32, - }, - Polyline { - points: Vec<(f32, f32)>, - }, - Polygon { - points: Vec<(f32, f32)>, - }, + Rect { width: f32, height: f32 }, + Ellipse { width: f32, height: f32 }, + Polyline { points: Vec<(f32, f32)> }, + Polygon { points: Vec<(f32, f32)> }, } #[derive(Debug, PartialEq, Clone)] @@ -675,20 +803,28 @@ pub struct Object { } impl Object { - fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Result<Object, TiledError> { - let ((id,gid,n,t,w, h, v, r), (x, y)) = get_attrs!( + fn new<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + ) -> Result<Object, TiledError> { + let ((id, gid, n, t, w, h, v, r), (x, y)) = get_attrs!( attrs, - optionals: [("id", id, |v:String| v.parse().ok()), - ("gid", gid, |v:String| v.parse().ok()), - ("name", name, |v:String| v.parse().ok()), - ("type", obj_type, |v:String| v.parse().ok()), - ("width", width, |v:String| v.parse().ok()), - ("height", height, |v:String| v.parse().ok()), - ("visible", visible, |v:String| v.parse().ok()), - ("rotation", rotation, |v:String| v.parse().ok())], - required: [("x", x, |v:String| v.parse().ok()), - ("y", y, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("objects must have an x and a y number".to_string())); + optionals: [ + ("id", id, |v:String| v.parse().ok()), + ("gid", gid, |v:String| v.parse().ok()), + ("name", name, |v:String| v.parse().ok()), + ("type", obj_type, |v:String| v.parse().ok()), + ("width", width, |v:String| v.parse().ok()), + ("height", height, |v:String| v.parse().ok()), + ("visible", visible, |v:String| v.parse().ok()), + ("rotation", rotation, |v:String| v.parse().ok()), + ], + required: [ + ("x", x, |v:String| v.parse().ok()), + ("y", y, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("objects must have an x and a y number".to_string()) + ); let v = v.unwrap_or(true); let w = w.unwrap_or(0f32); let h = h.unwrap_or(0f32); @@ -700,8 +836,7 @@ impl Object { let mut shape = None; let mut properties = HashMap::new(); - parse_tag!( - parser, "object", + parse_tag!(parser, "object", { "ellipse" => |_| { shape = Some(ObjectShape::Ellipse { width: w, @@ -720,8 +855,8 @@ impl Object { "properties" => |_| { properties = try!(parse_properties(parser)); Ok(()) - } - ); + }, + }); let shape = shape.unwrap_or(ObjectShape::Rect { width: w, @@ -746,24 +881,26 @@ impl Object { let ((), s) = get_attrs!( attrs, optionals: [], - required: [("points", points, |v| Some(v))], - TiledError::MalformedAttributes("A polyline must have points".to_string())); - let points = try!(Object::parse_points(s)); - Ok(ObjectShape::Polyline { - points: points, - }) + required: [ + ("points", points, |v| Some(v)), + ], + TiledError::MalformedAttributes("A polyline must have points".to_string()) + ); + let points = try!(Object::parse_points(s)); + Ok(ObjectShape::Polyline { points: points }) } fn new_polygon(attrs: Vec<OwnedAttribute>) -> Result<ObjectShape, TiledError> { let ((), s) = get_attrs!( attrs, optionals: [], - required: [("points", points, |v| Some(v))], - TiledError::MalformedAttributes("A polygon must have points".to_string())); - let points = try!(Object::parse_points(s)); - Ok(ObjectShape::Polygon { - points: points, - }) + required: [ + ("points", points, |v| Some(v)), + ], + TiledError::MalformedAttributes("A polygon must have points".to_string()) + ); + let points = try!(Object::parse_points(s)); + Ok(ObjectShape::Polygon { points: points }) } fn parse_points(s: String) -> Result<Vec<(f32, f32)>, TiledError> { @@ -772,11 +909,15 @@ impl Object { for v in pairs.map(|p| p.split(',')) { let v: Vec<&str> = v.collect(); if v.len() != 2 { - return Err(TiledError::MalformedAttributes("one of a polyline's points does not have an x and y coordinate".to_string())); + return Err(TiledError::MalformedAttributes( + "one of a polyline's points does not have an x and y coordinate".to_string(), + )); } let (x, y) = (v[0].parse().ok(), v[1].parse().ok()); if x.is_none() || y.is_none() { - return Err(TiledError::MalformedAttributes("one of polyline's points does not have i32eger coordinates".to_string())); + return Err(TiledError::MalformedAttributes( + "one of polyline's points does not have i32eger coordinates".to_string(), + )); } points.push((x.unwrap(), y.unwrap())); } @@ -795,9 +936,12 @@ impl Frame { let ((), (tile_id, duration)) = get_attrs!( attrs, optionals: [], - required: [("tileid", tile_id, |v:String| v.parse().ok()), - ("duration", duration, |v:String| v.parse().ok())], - TiledError::MalformedAttributes("A frame must have tileid and duration".to_string())); + required: [ + ("tileid", tile_id, |v:String| v.parse().ok()), + ("duration", duration, |v:String| v.parse().ok()), + ], + TiledError::MalformedAttributes("A frame must have tileid and duration".to_string()) + ); Ok(Frame { tile_id: tile_id, duration: duration, @@ -807,36 +951,59 @@ impl Frame { fn parse_animation<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<Frame>, TiledError> { let mut animation = Vec::new(); - parse_tag!(parser, "animation", - "frame" => |attrs| { - animation.push(try!(Frame::new(attrs))); - Ok(()) - }); + parse_tag!(parser, "animation", { + "frame" => |attrs| { + animation.push(try!(Frame::new(attrs))); + Ok(()) + }, + }); Ok(animation) } -fn parse_data<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, width: u32) -> Result<Vec<Vec<u32>>, TiledError> { +fn parse_data<R: Read>( + parser: &mut EventReader<R>, + attrs: Vec<OwnedAttribute>, + width: u32, +) -> Result<Vec<Vec<u32>>, TiledError> { let ((e, c), ()) = get_attrs!( attrs, - optionals: [("encoding", encoding, |v| Some(v)), - ("compression", compression, |v| Some(v))], + optionals: [ + ("encoding", encoding, |v| Some(v)), + ("compression", compression, |v| Some(v)), + ], required: [], - TiledError::MalformedAttributes("data must have an encoding and a compression".to_string())); - - match (e,c) { - (None,None) => return Err(TiledError::Other("XML format is currently not supported".to_string())), - (Some(e),None) => - match e.as_ref() { - "base64" => return parse_base64(parser).map(|v| convert_to_u32(&v,width)), - "csv" => return decode_csv(parser), - e => return Err(TiledError::Other(format!("Unknown encoding format {}",e))), - }, - (Some(e),Some(c)) => - match (e.as_ref(),c.as_ref()) { - ("base64","zlib") => return parse_base64(parser).and_then(decode_zlib).map(|v| convert_to_u32(&v,width) ), - ("base64","gzip") => return parse_base64(parser).and_then(decode_gzip).map(|v| convert_to_u32(&v,width)), - (e,c) => return Err(TiledError::Other(format!("Unknown combination of {} encoding and {} compression",e,c))) - }, + TiledError::MalformedAttributes("data must have an encoding and a compression".to_string()) + ); + + match (e, c) { + (None, None) => { + return Err(TiledError::Other( + "XML format is currently not supported".to_string(), + )) + } + (Some(e), None) => match e.as_ref() { + "base64" => return parse_base64(parser).map(|v| convert_to_u32(&v, width)), + "csv" => return decode_csv(parser), + e => return Err(TiledError::Other(format!("Unknown encoding format {}", e))), + }, + (Some(e), Some(c)) => match (e.as_ref(), c.as_ref()) { + ("base64", "zlib") => { + return parse_base64(parser) + .and_then(decode_zlib) + .map(|v| convert_to_u32(&v, width)) + } + ("base64", "gzip") => { + return parse_base64(parser) + .and_then(decode_gzip) + .map(|v| convert_to_u32(&v, width)) + } + (e, c) => { + return Err(TiledError::Other(format!( + "Unknown combination of {} encoding and {} compression", + e, c + ))) + } + }, _ => return Err(TiledError::Other("Missing encoding format".to_string())), }; } @@ -844,9 +1011,10 @@ fn parse_data<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>, fn parse_base64<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<u8>, TiledError> { loop { match try!(parser.next().map_err(TiledError::XmlDecodingError)) { - XmlEvent::Characters(s) => return base64::decode(s.trim().as_bytes()) - .map_err(TiledError::Base64DecodingError), - XmlEvent::EndElement {name, ..} => { + XmlEvent::Characters(s) => { + return base64::decode(s.trim().as_bytes()).map_err(TiledError::Base64DecodingError) + } + XmlEvent::EndElement { name, .. } => { if name.local_name == "data" { return Ok(Vec::new()); } @@ -857,24 +1025,25 @@ fn parse_base64<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<u8>, TiledEr } fn decode_zlib(data: Vec<u8>) -> Result<Vec<u8>, TiledError> { - use libflate::zlib::{Decoder}; - let mut zd = Decoder::new(BufReader::new(&data[..])) - .map_err(|e|TiledError::DecompressingError(e))?; + use libflate::zlib::Decoder; + let mut zd = + Decoder::new(BufReader::new(&data[..])).map_err(|e| TiledError::DecompressingError(e))?; let mut data = Vec::new(); match zd.read_to_end(&mut data) { - Ok(_v) => {}, - Err(e) => return Err(TiledError::DecompressingError(e)) + Ok(_v) => {} + Err(e) => return Err(TiledError::DecompressingError(e)), } Ok(data) } fn decode_gzip(data: Vec<u8>) -> Result<Vec<u8>, TiledError> { - use libflate::gzip::{Decoder}; - let mut zd = Decoder::new(BufReader::new(&data[..])) - .map_err(|e|TiledError::DecompressingError(e))?; + use libflate::gzip::Decoder; + let mut zd = + Decoder::new(BufReader::new(&data[..])).map_err(|e| TiledError::DecompressingError(e))?; let mut data = Vec::new(); - zd.read_to_end(&mut data).map_err(|e| TiledError::DecompressingError(e))?; + zd.read_to_end(&mut data) + .map_err(|e| TiledError::DecompressingError(e))?; Ok(data) } @@ -887,11 +1056,16 @@ fn decode_csv<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<Vec<u32>>, Til if row.trim() == "" { continue; } - rows.push(row.split(',').filter(|v| v.trim() != "").map(|v| v.replace('\r', "").parse().unwrap()).collect()); + rows.push( + row.split(',') + .filter(|v| v.trim() != "") + .map(|v| v.replace('\r', "").parse().unwrap()) + .collect(), + ); } return Ok(rows); } - XmlEvent::EndElement {name, ..} => { + XmlEvent::EndElement { name, .. } => { if name.local_name == "data" { return Ok(Vec::new()); } @@ -905,12 +1079,12 @@ fn convert_to_u32(all: &Vec<u8>, width: u32) -> Vec<Vec<u32>> { let mut data = Vec::new(); for chunk in all.chunks((width * 4) as usize) { let mut row = Vec::new(); - for i in 0 .. width { + for i in 0..width { let start: usize = i as usize * 4; - let n = ((chunk[start + 3] as u32) << 24) + - ((chunk[start + 2] as u32) << 16) + - ((chunk[start + 1] as u32) << 8) + - chunk[start] as u32; + let n = ((chunk[start + 3] as u32) << 24) + + ((chunk[start + 2] as u32) << 16) + + ((chunk[start + 1] as u32) << 8) + + chunk[start] as u32; row.push(n); } data.push(row); @@ -922,12 +1096,18 @@ fn parse_impl<R: Read>(reader: R, map_path: Option<&Path>) -> Result<Map, TiledE let mut parser = EventReader::new(reader); loop { match try!(parser.next().map_err(TiledError::XmlDecodingError)) { - XmlEvent::StartElement {name, attributes, ..} => { + XmlEvent::StartElement { + name, attributes, .. + } => { if name.local_name == "map" { return Map::new(&mut parser, attributes, map_path); } } - XmlEvent::EndDocument => return Err(TiledError::PrematureEnd("Document ended before map was parsed".to_string())), + XmlEvent::EndDocument => { + return Err(TiledError::PrematureEnd( + "Document ended before map was parsed".to_string(), + )) + } _ => {} } } @@ -945,7 +1125,8 @@ pub fn parse_with_path<R: Read>(reader: R, path: &Path) -> Result<Map, TiledErro /// file has an external tileset, the tileset file will be loaded using a path /// relative to the map file's path. pub fn parse_file(path: &Path) -> Result<Map, TiledError> { - let file = File::open(path).map_err(|_| TiledError::Other(format!("Map file not found: {:?}", path)))?; + let file = File::open(path) + .map_err(|_| TiledError::Other(format!("Map file not found: {:?}", path)))?; parse_impl(file, Some(path)) } -- GitLab