use std::collections::HashMap;
use crate::{
Result, TileId,
properties::{Properties, parse_properties},
util::{get_attrs, parse_tag},
};
mod wang_color;
pub use wang_color::*;
mod wang_tile;
pub use wang_tile::*;
#[derive(Debug, Default, PartialEq, Clone, Copy)]
#[allow(missing_docs)]
pub enum WangSetType {
Corner,
Edge,
#[default]
Mixed,
}
#[derive(Debug, PartialEq, Clone)]
pub struct WangSet {
pub name: String,
pub user_type: String,
pub wang_set_type: WangSetType,
pub tile: Option<TileId>,
pub wang_colors: Vec<WangColor>,
pub wang_tiles: HashMap<TileId, WangTile>,
pub properties: Properties,
}
impl WangSet {
pub(crate) fn new<R: std::io::BufRead>(
elem: crate::util::XmlElement<'_, R>,
) -> Result<WangSet> {
let ((user_type,), (name, wang_set_type, tile)) = get_attrs!(
for v in (elem.attrs) {
Some("class") => user_type ?= v.parse::<String>(),
"name" => name ?= v.parse::<String>(),
"type" => wang_set_type ?= v.parse::<String>(),
"tile" => tile ?= v.parse::<i64>(),
}
((user_type,), (name, wang_set_type, tile))
);
let wang_set_type = match wang_set_type.as_str() {
"corner" => WangSetType::Corner,
"edge" => WangSetType::Edge,
_ => WangSetType::default(),
};
let tile = if tile >= 0 { Some(tile as u32) } else { None };
let mut wang_colors = Vec::new();
let mut wang_tiles = HashMap::new();
let mut properties = HashMap::new();
parse_tag!(elem, {
"wangcolor" => |elem| {
let color = WangColor::new(elem)?;
wang_colors.push(color);
Ok(())
},
"wangtile" => |elem| {
let (id, t) = WangTile::new(elem)?;
wang_tiles.insert(id, t);
Ok(())
},
"properties" => |elem| {
properties = parse_properties(elem)?;
Ok(())
},
});
Ok(WangSet {
name,
user_type: user_type.unwrap_or_default(),
wang_set_type,
tile,
wang_colors,
wang_tiles,
properties,
})
}
}