1use core::{ops::Range, str};
6
7use arrayvec::{ArrayString, ArrayVec};
8
9use super::{
10 audio_clip::AudioClipAsset,
11 chunks::{ChunkDescriptor, SpriteChunkDescriptor},
12 sprite::{SpriteAsset, SpriteMipLevel, MAX_MIPS},
13 NamedAsset, ResourceDatabaseHeader, ASSET_NAME_LENGTH,
14};
15
16pub trait Deserialize {
19 const SERIALIZED_SIZE: usize;
21 fn deserialize(src: &[u8]) -> Self;
24}
25
26impl Deserialize for ChunkDescriptor {
27 const SERIALIZED_SIZE: usize = <Range<u64> as Deserialize>::SERIALIZED_SIZE;
28 fn deserialize(src: &[u8]) -> Self {
29 assert_eq!(Self::SERIALIZED_SIZE, src.len());
30 let mut cursor = 0;
31 Self {
32 source_bytes: deserialize::<Range<u64>>(src, &mut cursor),
33 }
34 }
35}
36
37impl Deserialize for SpriteChunkDescriptor {
38 const SERIALIZED_SIZE: usize =
39 u16::SERIALIZED_SIZE * 2 + <Range<u64> as Deserialize>::SERIALIZED_SIZE;
40 fn deserialize(src: &[u8]) -> Self {
41 assert_eq!(Self::SERIALIZED_SIZE, src.len());
42 let mut cursor = 0;
43 Self {
44 region_width: deserialize::<u16>(src, &mut cursor),
45 region_height: deserialize::<u16>(src, &mut cursor),
46 source_bytes: deserialize::<Range<u64>>(src, &mut cursor),
47 }
48 }
49}
50
51impl Deserialize for ResourceDatabaseHeader {
52 const SERIALIZED_SIZE: usize = 18 + u32::SERIALIZED_SIZE * 4;
53 fn deserialize(src: &[u8]) -> Self {
54 assert_eq!(Self::SERIALIZED_SIZE, src.len());
55 let mut cursor = 0;
56
57 {
58 use super::*;
59 use platform::*;
60
61 let magic = deserialize::<u32>(src, &mut cursor);
62 assert_eq!(RESOURCE_DB_MAGIC_NUMBER, magic);
63 let chunk_size = deserialize::<u32>(src, &mut cursor);
64 assert_eq!(CHUNK_SIZE, chunk_size);
65 let sprite_chunk_width = deserialize::<u16>(src, &mut cursor);
66 assert_eq!(SPRITE_CHUNK_DIMENSIONS.0, sprite_chunk_width);
67 let sprite_chunk_height = deserialize::<u16>(src, &mut cursor);
68 assert_eq!(SPRITE_CHUNK_DIMENSIONS.1, sprite_chunk_height);
69 let sprite_chunk_format = deserialize::<u8>(src, &mut cursor);
70 assert_eq!(SPRITE_CHUNK_FORMAT as u8, sprite_chunk_format);
71 let audio_sample_rate = deserialize::<u32>(src, &mut cursor);
72 assert_eq!(AUDIO_SAMPLE_RATE, audio_sample_rate);
73 let audio_channels = deserialize::<u8>(src, &mut cursor);
74 assert_eq!((AUDIO_CHANNELS as u8), audio_channels);
75 }
76
77 Self {
78 chunks: deserialize::<u32>(src, &mut cursor),
79 sprite_chunks: deserialize::<u32>(src, &mut cursor),
80 sprites: deserialize::<u32>(src, &mut cursor),
81 audio_clips: deserialize::<u32>(src, &mut cursor),
82 }
83 }
84}
85
86impl<D: Deserialize> Deserialize for NamedAsset<D> {
87 const SERIALIZED_SIZE: usize =
88 <ArrayString<ASSET_NAME_LENGTH> as Deserialize>::SERIALIZED_SIZE + D::SERIALIZED_SIZE;
89 fn deserialize(src: &[u8]) -> Self {
90 assert_eq!(Self::SERIALIZED_SIZE, src.len());
91 let mut cursor = 0;
92 Self {
93 name: deserialize::<ArrayString<ASSET_NAME_LENGTH>>(src, &mut cursor),
94 asset: deserialize::<D>(src, &mut cursor),
95 }
96 }
97}
98
99impl Deserialize for AudioClipAsset {
100 const SERIALIZED_SIZE: usize =
101 u32::SERIALIZED_SIZE + <Range<u32> as Deserialize>::SERIALIZED_SIZE;
102 fn deserialize(src: &[u8]) -> Self {
103 assert_eq!(Self::SERIALIZED_SIZE, src.len());
104 let mut cursor = 0;
105 Self {
106 samples: deserialize::<u32>(src, &mut cursor),
107 chunks: deserialize::<Range<u32>>(src, &mut cursor),
108 }
109 }
110}
111
112impl Deserialize for SpriteAsset {
113 const SERIALIZED_SIZE: usize = bool::SERIALIZED_SIZE
114 + <ArrayVec<SpriteMipLevel, MAX_MIPS> as Deserialize>::SERIALIZED_SIZE;
115 fn deserialize(src: &[u8]) -> Self {
116 assert_eq!(Self::SERIALIZED_SIZE, src.len());
117 let mut cursor = 0;
118 Self {
119 transparent: deserialize::<bool>(src, &mut cursor),
120 mip_chain: deserialize::<ArrayVec<SpriteMipLevel, MAX_MIPS>>(src, &mut cursor),
121 }
122 }
123}
124
125impl Deserialize for SpriteMipLevel {
126 const SERIALIZED_SIZE: usize = bool::SERIALIZED_SIZE + 12;
129 fn deserialize(src: &[u8]) -> Self {
130 assert_eq!(Self::SERIALIZED_SIZE, src.len());
131 let mut cursor = 0;
132 let multi_chunk = deserialize::<bool>(src, &mut cursor);
133 if multi_chunk {
134 Self::MultiChunkSprite {
135 size: deserialize::<(u16, u16)>(src, &mut cursor),
136 sprite_chunks: deserialize::<Range<u32>>(src, &mut cursor),
137 }
138 } else {
139 Self::SingleChunkSprite {
140 offset: deserialize::<(u16, u16)>(src, &mut cursor),
141 size: deserialize::<(u16, u16)>(src, &mut cursor),
142 sprite_chunk: deserialize::<u32>(src, &mut cursor),
143 }
144 }
145 }
146}
147
148#[inline(always)]
154pub fn deserialize<D: Deserialize>(src: &[u8], cursor: &mut usize) -> D {
155 let value = D::deserialize(&src[*cursor..(*cursor + D::SERIALIZED_SIZE)]);
156 *cursor += D::SERIALIZED_SIZE;
157 value
158}
159
160impl<const LEN: usize> Deserialize for ArrayString<LEN> {
161 const SERIALIZED_SIZE: usize = u8::SERIALIZED_SIZE + LEN;
162 fn deserialize(src: &[u8]) -> Self {
163 assert_eq!(Self::SERIALIZED_SIZE, src.len());
164 assert!(
165 LEN < 0xFF,
166 "deserialization impl for ArrayString only supports string lengths up to 255",
167 );
168 let len = src[0] as usize;
169 assert!(len <= LEN, "serialized string cannot fit");
170 ArrayString::from(str::from_utf8(&src[1..1 + len]).unwrap()).unwrap()
171 }
172}
173
174impl<T: Deserialize, const LEN: usize> Deserialize for ArrayVec<T, LEN> {
175 const SERIALIZED_SIZE: usize = u8::SERIALIZED_SIZE + T::SERIALIZED_SIZE * LEN;
176 fn deserialize(src: &[u8]) -> Self {
177 assert_eq!(Self::SERIALIZED_SIZE, src.len());
178 assert!(
179 LEN < 0xFF,
180 "deserialization impl for ArrayVec only supports lengths up to 255",
181 );
182 let mut cursor = 0;
183 let len = deserialize::<u8>(src, &mut cursor) as usize;
184 assert!(len <= LEN, "serialized vec cannot fit");
185 let mut vec = ArrayVec::new();
186 for _ in 0..len {
187 vec.push(deserialize::<T>(src, &mut cursor));
188 }
189 vec
190 }
191}
192
193impl Deserialize for Range<u64> {
194 const SERIALIZED_SIZE: usize = u64::SERIALIZED_SIZE * 2;
195 #[inline]
196 fn deserialize(src: &[u8]) -> Self {
197 assert_eq!(Self::SERIALIZED_SIZE, src.len());
198 let start = u64::deserialize(&src[0..8]);
199 let end = u64::deserialize(&src[8..16]);
200 start..end
201 }
202}
203
204impl Deserialize for Range<u32> {
205 const SERIALIZED_SIZE: usize = u32::SERIALIZED_SIZE * 2;
206 #[inline]
207 fn deserialize(src: &[u8]) -> Self {
208 assert_eq!(Self::SERIALIZED_SIZE, src.len());
209 let start = u32::deserialize(&src[0..4]);
210 let end = u32::deserialize(&src[4..8]);
211 start..end
212 }
213}
214
215impl Deserialize for (u16, u16) {
216 const SERIALIZED_SIZE: usize = u16::SERIALIZED_SIZE * 2;
217 #[inline]
218 fn deserialize(src: &[u8]) -> Self {
219 assert_eq!(Self::SERIALIZED_SIZE, src.len());
220 let u0 = u16::deserialize(&src[0..2]);
221 let u1 = u16::deserialize(&src[2..4]);
222 (u0, u1)
223 }
224}
225
226impl Deserialize for bool {
227 const SERIALIZED_SIZE: usize = 1;
228 #[inline]
229 fn deserialize(src: &[u8]) -> Self {
230 assert_eq!(Self::SERIALIZED_SIZE, src.len());
231 unsafe { *src.get_unchecked(0) != 0 }
233 }
234}
235
236impl Deserialize for u8 {
237 const SERIALIZED_SIZE: usize = 1;
238 #[inline]
239 fn deserialize(src: &[u8]) -> Self {
240 assert_eq!(Self::SERIALIZED_SIZE, src.len());
241 unsafe { *src.get_unchecked(0) }
243 }
244}
245
246impl Deserialize for u16 {
247 const SERIALIZED_SIZE: usize = 2;
248 #[inline]
249 fn deserialize(src: &[u8]) -> Self {
250 assert_eq!(Self::SERIALIZED_SIZE, src.len());
251 let bytes = unsafe { [*src.get_unchecked(0), *src.get_unchecked(1)] };
253 u16::from_le_bytes(bytes)
254 }
255}
256
257impl Deserialize for u32 {
258 const SERIALIZED_SIZE: usize = 4;
259 #[inline]
260 fn deserialize(src: &[u8]) -> Self {
261 assert_eq!(Self::SERIALIZED_SIZE, src.len());
262 let bytes = unsafe {
264 [
265 *src.get_unchecked(0),
266 *src.get_unchecked(1),
267 *src.get_unchecked(2),
268 *src.get_unchecked(3),
269 ]
270 };
271 u32::from_le_bytes(bytes)
272 }
273}
274
275impl Deserialize for u64 {
276 const SERIALIZED_SIZE: usize = 8;
277 #[inline]
278 fn deserialize(src: &[u8]) -> Self {
279 assert_eq!(Self::SERIALIZED_SIZE, src.len());
280 let bytes = unsafe {
282 [
283 *src.get_unchecked(0),
284 *src.get_unchecked(1),
285 *src.get_unchecked(2),
286 *src.get_unchecked(3),
287 *src.get_unchecked(4),
288 *src.get_unchecked(5),
289 *src.get_unchecked(6),
290 *src.get_unchecked(7),
291 ]
292 };
293 u64::from_le_bytes(bytes)
294 }
295}