sprite_sheet_file_type/
mapping.rs1use serde::{Deserialize, Serialize};
5use serde_json;
6
7use std::collections::HashMap;
8
9use std::fs::File;
10use std::io::{BufReader, BufWriter, Cursor, Error, ErrorKind, Read, Result, Write};
11use std::path::Path;
12
13const MAPPING_VERSION_NUMBER: u8 = 0;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct Rect {
19 pub x: u32,
20 pub y: u32,
21 pub w: u32,
22 pub h: u32,
23}
24
25#[derive(Serialize, Deserialize, Clone)]
27pub struct SpriteSheetMetaData {
28 pub mapping: HashMap<String, Rect>,
29}
30impl SpriteSheetMetaData {
31 pub fn save_json<P: AsRef<Path>>(&self, path: P) -> Result<()> {
33 let file = File::create(path)?;
34 let writer = BufWriter::new(file);
35 serde_json::to_writer(writer, self)?;
36
37 Ok(())
38 }
39
40 pub fn load_json<P: AsRef<Path>>(path: P) -> Result<Self> {
42 let file = File::open(path)?;
43 let reader = BufReader::new(file);
44 Ok(serde_json::from_reader(reader)?)
45 }
46
47 pub fn save_raw<P: AsRef<Path>>(&self, path: P) -> Result<()> {
49 let file = File::create(path)?;
50 let mut writer = BufWriter::new(file);
51 self.to_writer(&mut writer)?;
52 writer.flush()?;
53 Ok(())
54 }
55
56 pub fn load_raw<P: AsRef<Path>>(path: P) -> Result<Self> {
58 let file = File::open(path)?;
59 let mut reader = BufReader::new(file);
60 Self::from_reader(&mut reader)
61 }
62
63 pub fn to_bytes(&self) -> Vec<u8> {
65 let mut bytes = Vec::new();
66 self.to_writer(&mut bytes).unwrap();
67 bytes
68 }
69
70 pub fn from_bytes(bytes: Vec<u8>) -> Result<Self> {
72 let mut reader = BufReader::new(Cursor::new(bytes));
73 Self::from_reader(&mut reader)
74 }
75
76 pub fn to_writer<W: Write>(&self, writer: &mut W) -> Result<()> {
78 writer.write(&[MAPPING_VERSION_NUMBER])?;
80 writer.write(&(self.mapping.len() as u32).to_le_bytes())?;
81
82 for (key, value) in self.mapping.iter() {
84 writer.write(&(key.bytes().len() as u32).to_le_bytes())?;
86 writer.write(key.as_bytes())?;
87
88 let mut rect_values = Vec::with_capacity(16);
90 rect_values.extend(value.x.to_le_bytes());
91 rect_values.extend(value.y.to_le_bytes());
92 rect_values.extend(value.w.to_le_bytes());
93 rect_values.extend(value.h.to_le_bytes());
94 writer.write(&rect_values)?;
95 }
96 writer.flush()?;
97
98 Ok(())
99 }
100
101 pub fn from_reader<R: Read>(reader: &mut R) -> Result<Self> {
103 let mut buf = [0u8; 1];
105 reader.read_exact(&mut buf)?;
106 let version_number = u8::from_le_bytes(buf);
107
108 if version_number != MAPPING_VERSION_NUMBER {
109 return Err(Error::new(
110 ErrorKind::InvalidData,
111 "Unsupported file version",
112 ));
113 }
114
115 let mut buf = [0u8; 4];
116 reader.read_exact(&mut buf)?;
117 let entry_count = u32::from_le_bytes(buf);
118
119 let mut mapping = HashMap::new();
121 for _ in 0..entry_count {
122 let mut buf = [0u8; 4];
124 reader.read_exact(&mut buf)?;
125 let string_length = u32::from_le_bytes(buf);
126
127 let mut key_buf = vec![0u8; string_length as usize];
129 reader.read_exact(&mut key_buf)?;
130 let key = String::from_utf8(key_buf)
131 .map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid UTF-8 string"))?;
132
133 let mut rect_buf = [0u8; 16]; reader.read_exact(&mut rect_buf)?;
136 let rect = Rect {
137 x: u32::from_le_bytes(rect_buf[0..4].try_into().unwrap()),
138 y: u32::from_le_bytes(rect_buf[4..8].try_into().unwrap()),
139 w: u32::from_le_bytes(rect_buf[8..12].try_into().unwrap()),
140 h: u32::from_le_bytes(rect_buf[12..16].try_into().unwrap()),
141 };
142
143 mapping.insert(key, rect);
145 }
146
147 Ok(Self { mapping })
148 }
149
150 pub fn empty() -> Self {
151 Self { mapping: HashMap::new() }
152 }
153
154 pub fn len(&self) -> usize {
155 self.mapping.len()
156 }
157}