1use std::collections::HashMap;
2
3use xml::attribute::OwnedAttribute;
4
5use crate::{
6 error::Error,
7 properties::{parse_properties, Properties},
8 util::{get_attrs, parse_tag, XmlEventResult},
9 Result, TileId,
10};
11
12mod wang_color;
13pub use wang_color::*;
14mod wang_tile;
15pub use wang_tile::*;
16
17#[derive(Debug, PartialEq, Clone, Copy)]
19#[allow(missing_docs)]
20pub enum WangSetType {
21 Corner,
22 Edge,
23 Mixed,
24}
25
26impl Default for WangSetType {
27 fn default() -> Self {
28 WangSetType::Mixed
29 }
30}
31
32#[derive(Debug, PartialEq, Clone)]
34pub struct WangSet {
35 pub name: String,
37 pub wang_set_type: WangSetType,
39 pub tile: Option<TileId>,
41 pub wang_colors: Vec<WangColor>,
43 pub wang_tiles: HashMap<TileId, WangTile>,
45 pub properties: Properties,
47}
48
49impl WangSet {
50 pub fn new(
52 parser: &mut impl Iterator<Item = XmlEventResult>,
53 attrs: Vec<OwnedAttribute>,
54 ) -> Result<WangSet> {
55 let (name, wang_set_type, tile) = get_attrs!(
57 for v in attrs {
58 "name" => name ?= v.parse::<String>(),
59 "type" => wang_set_type ?= v.parse::<String>(),
60 "tile" => tile ?= v.parse::<i64>(),
61 }
62 (name, wang_set_type, tile)
63 );
64
65 let wang_set_type = match wang_set_type.as_str() {
66 "corner" => WangSetType::Corner,
67 "edge" => WangSetType::Edge,
68 _ => WangSetType::default(),
69 };
70 let tile = if tile >= 0 { Some(tile as u32) } else { None };
71
72 let mut wang_colors = Vec::new();
74 let mut wang_tiles = HashMap::new();
75 let mut properties = HashMap::new();
76 parse_tag!(parser, "wangset", {
77 "wangcolor" => |attrs| {
78 let color = WangColor::new(parser, attrs)?;
79 wang_colors.push(color);
80 Ok(())
81 },
82 "wangtile" => |attrs| {
83 let (id, t) = WangTile::new(parser, attrs)?;
84 wang_tiles.insert(id, t);
85 Ok(())
86 },
87 "properties" => |_| {
88 properties = parse_properties(parser)?;
89 Ok(())
90 },
91 });
92
93 Ok(WangSet {
94 name,
95 wang_set_type,
96 tile,
97 wang_colors,
98 wang_tiles,
99 properties,
100 })
101 }
102}