ct_tilemap/
formatting.rs

1use crate::{Layer, Property, SubLayer, Tile, TileMap, TileSet};
2use fmt::Debug;
3use std::fmt;
4use std::fmt::{Display, Formatter, Write};
5
6impl Debug for Layer {
7    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
8        if f.alternate() {
9            writeln!(f, "Layer {{")?;
10            let mut buf = String::new();
11            write!(buf, "data: [")?;
12            // Write data
13            let w = self.width as usize;
14            let h = self.height as usize;
15            if w == 0 || h == 0 {
16                writeln!(buf, "]\n,")?;
17            } else {
18                for (i, tile) in self.data.as_slice().iter().enumerate() {
19                    if i % w == 0 {
20                        // Write newline and padding
21                        write!(buf, "\n    ")?;
22                    }
23                    // Write cell
24                    write!(buf, "0x{tile}")?;
25                    // Check if at end
26                    if !(i % w == (w - 1) && i / w == h - 1) {
27                        write!(buf, ", ")?;
28                    }
29                }
30                writeln!(buf, "\n],")?;
31            }
32            writeln!(buf, "width: {:?},", self.width)?;
33            writeln!(buf, "height: {:?},", self.height)?;
34            writeln!(buf, "tileset: {:?},", self.tileset)?;
35            writeln!(buf, "collision: {:?},", self.collision)?;
36            writeln!(buf, "offset: {:?},", self.offset)?;
37            writeln!(buf, "scroll: {:?},", self.scroll)?;
38            writeln!(buf, "wrap: {:?},", self.wrap)?;
39            writeln!(buf, "visible: {:?},", self.visible)?;
40            writeln!(buf, "opacity: {:?},", self.opacity)?;
41            writeln!(buf, "tile_dimensions: {:?},", self.tile_dimensions)?;
42            writeln!(buf, "sublayer_link: {:?},", self.sublayer_link)?;
43            writeln!(buf, "sublayers: {:#?},", self.sublayers)?;
44            // Pad lines
45            for line in buf.lines() {
46                writeln!(f, "    {line}")?;
47            }
48            write!(f, "}}")
49        } else {
50            write!(f, "Layer {{ ")?;
51            write!(f, "data: {:?}, ", self.data)?;
52            write!(f, "width: {:?}, ", self.width)?;
53            write!(f, "height: {:?}, ", self.height)?;
54            write!(f, "tileset: {:?}, ", self.tileset)?;
55            write!(f, "collision: {:?}, ", self.collision)?;
56            write!(f, "offset: {:?}, ", self.offset)?;
57            write!(f, "scroll: {:?}, ", self.scroll)?;
58            write!(f, "wrap: {:?}, ", self.wrap)?;
59            write!(f, "visible: {:?}, ", self.visible)?;
60            write!(f, "opacity: {:?}, ", self.opacity)?;
61            write!(f, "tile_dimensions: {:?}, ", self.tile_dimensions)?;
62            write!(f, "sublayer_link: {:?}, ", self.sublayer_link)?;
63            write!(f, "sublayers: {:?} }}", self.sublayers)
64        }
65    }
66}
67
68impl Debug for Property {
69    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
70        match self {
71            Property::Integer(i) => write!(fmt, "{i}"),
72            Property::Float(f) => write!(fmt, "{f:?}"),
73            Property::String(b) => {
74                let escaped = b
75                    .iter()
76                    .copied()
77                    .flat_map(std::ascii::escape_default)
78                    .collect::<Vec<u8>>();
79                write!(fmt, "\"{}\"", unsafe {
80                    // SAFETY: escape_default always
81                    // gives back valid UTF-8
82                    String::from_utf8_unchecked(escaped)
83                })
84            }
85        }
86    }
87}
88
89impl Display for Tile {
90    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
91        write!(f, "{self:#?}")
92    }
93}
94
95impl Debug for Tile {
96    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97        // SAFETY: This is always valid due to every union element having the same size.
98        if f.alternate() {
99            // Write only ID in pretty print
100            write!(f, "{:04X}", unsafe { self.id })
101        } else {
102            write!(f, "Tile({:04X})", unsafe { self.id })
103        }
104    }
105}
106
107impl Debug for SubLayer {
108    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
109        if f.alternate() {
110            f.write_str("SubLayer {\n    data: [")?;
111            // Write each cell, space-separated
112            let chunk_size = self.cell_size as usize;
113            let w = self.width as usize;
114            let h = self.height as usize;
115            if w == 0 {
116                f.write_str("],\n")?;
117            } else {
118                for (i, cell) in self.data.as_slice().chunks(chunk_size).enumerate() {
119                    if i % w == 0 {
120                        // Write newline and padding
121                        f.write_str("\n        ")?;
122                    }
123                    f.write_str("0x")?;
124                    // Write cell
125                    for byte in cell {
126                        write!(f, "{byte:02X}")?;
127                    }
128                    // Check if at end
129                    if !(i % w == (w - 1) && i / w == h - 1) {
130                        f.write_str(", ")?;
131                    }
132                }
133                f.write_str("\n    ],")?;
134            }
135            f.write_str("\n    default_value: 0x")?;
136            for byte in &self.default_value[..self.cell_size as usize] {
137                write!(f, "{byte:02X}")?;
138            }
139            write!(
140                f,
141                ",\n    width: {},\n    height: {}\n}}",
142                self.width, self.height
143            )
144        } else {
145            write!(
146                f, "SubLayer{{ data: {:02X?}, default_value: {:02X?}, cell_size: {}, width: {}, height: {} }}",
147                self.data,
148                self.default_value,
149                self.cell_size,
150                self.width,
151                self.height
152            )
153        }
154    }
155}
156
157impl Debug for TileMap {
158    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
159        writeln!(f, "TileMap {{")?;
160        let mut buf = String::new();
161        writeln!(buf, "layers: {:#?},", self.layers)?;
162        writeln!(buf, "tilesets: {:#?},", self.tilesets)?;
163        writeln!(buf, "properties: {:#?}", self.properties)?;
164        // Pad lines
165        for line in buf.lines() {
166            writeln!(f, "    {line}")?;
167        }
168        write!(f, "}}")
169    }
170}
171
172impl Debug for TileSet {
173    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
174        if f.alternate() {
175            write!(
176                f,
177                "TileSet {{\n    path: {:#?},\n    transparent_color: #{:02X}{:02X}{:02X}\n}}",
178                self.path,
179                self.transparent_color.0,
180                self.transparent_color.1,
181                self.transparent_color.2
182            )
183        } else {
184            write!(
185                f,
186                "TileSet {{ path: {:?}, transparent_color: {:?} }}",
187                self.path, self.transparent_color
188            )
189        }
190    }
191}