Newer
Older
/// Loops through the attributes once and pulls out the ones we ask it to. It
/// will check that the required ones are there. This could have been done with
/// attrs.find but that would be inefficient.
macro_rules! get_attrs {
($attrs:expr, optionals: [$(($oName:pat, $oVar:ident, $oMethod:expr)),+ $(,)*]
, required: [$(($name:pat, $var:ident, $method:expr)),+ $(,)*], $err:expr) => {
$crate::util::match_attrs!($attrs, match: [$(($oName, $oVar, $oMethod)),+, $(($name, $var, $method)),+]);
if !(true $(&& $var.is_some())*) {
return Err($err);
(
($($oVar),*),
($($var.unwrap()),*)
)
}
};
($attrs:expr, optionals: [$(($oName:pat, $oVar:ident, $oMethod:expr)),+ $(,)*]) => {
{
$(let mut $oVar = None;)+
$crate::util::match_attrs!($attrs, match: [$(($oName, $oVar, $oMethod)),+]);
($($oVar),*)
}
};
($attrs:expr, required: [$(($name:pat, $var:ident, $method:expr)),+ $(,)*], $err:expr) => {
{
$(let mut $var = None;)*
$crate::util::match_attrs!($attrs, match: [$(($name, $var, $method)),+]);
if !(true $(&& $var.is_some())*) {
return Err($err);
}
($($var.unwrap()),*)
}
};
}
macro_rules! match_attrs {
($attrs:expr, match: [$(($name:pat, $var:ident, $method:expr)),*]) => {
for attr in $attrs.iter() {
match <String as AsRef<str>>::as_ref(&attr.name.local_name) {
$($name => $var = $method(attr.value.clone()),)*
_ => {}
}
}
}
}
/// Goes through the children of the tag and will call the correct function for
macro_rules! parse_tag {
($parser:expr, $close_tag:expr, {$($open_tag:expr => $open_method:expr),* $(,)*}) => {
while let Some(next) = $parser.next() {
match next.map_err(TiledError::XmlDecodingError)? {
#[allow(unused_variables)]
$(
xml::reader::XmlEvent::StartElement {name, attributes, ..}
if name.local_name == $open_tag => $open_method(attributes)?,
)*
xml::reader::XmlEvent::EndElement {name, ..} => if name.local_name == $close_tag {
break;
xml::reader::XmlEvent::EndDocument => {
return Err(TiledError::PrematureEnd("Document ended before we expected.".to_string()));
/// Creates a new type that wraps an internal data type over along with a map.
macro_rules! map_wrapper {
($(#[$attrs:meta])* $name:ident => $data_ty:ty) => {
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct $name<'map> {
pub(crate) map: &'map $crate::Map,
pub(crate) data: &'map $data_ty,
}
impl<'map> $name<'map> {
pub(crate) fn new(map: &'map $crate::Map, data: &'map $data_ty) -> Self {
Self { map, data }
}
/// Get the map this object is from.
pub fn map(&self) -> &'map $crate::Map {
self.map
}
}
};
}
pub(crate) use map_wrapper;
pub(crate) type XmlEventResult = xml::reader::Result<xml::reader::XmlEvent>;
/// Returns both the tileset and its index
pub(crate) fn get_tileset_for_gid(
tilesets: &[MapTilesetGid],
gid: Gid,
) -> Option<(usize, &MapTilesetGid)> {
tilesets
.iter()
.enumerate()
.rev()
.find(|(_idx, ts)| ts.first_gid <= gid)