wow_alchemy_data/
std_impls.rs

1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2
3use crate::error::Result;
4
5use super::types::*;
6
7impl WowHeaderR for u32 {
8    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
9        Ok(reader.read_u32::<LittleEndian>()?)
10    }
11}
12impl WowHeaderW for u32 {
13    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
14        writer.write_u32::<LittleEndian>(*self)?;
15        Ok(())
16    }
17
18    fn wow_size(&self) -> usize {
19        4
20    }
21}
22
23impl WowHeaderR for (u32, u32) {
24    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
25        Ok((reader.wow_read()?, reader.wow_read()?))
26    }
27}
28impl WowHeaderW for (u32, u32) {
29    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
30        writer.wow_write(&self.0)?;
31        writer.wow_write(&self.1)?;
32        Ok(())
33    }
34
35    fn wow_size(&self) -> usize {
36        8
37    }
38}
39
40impl WowHeaderR for [u32; 3] {
41    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
42        Ok([reader.wow_read()?, reader.wow_read()?, reader.wow_read()?])
43    }
44}
45impl WowHeaderW for [u32; 3] {
46    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
47        writer.wow_write(&self[0])?;
48        writer.wow_write(&self[1])?;
49        writer.wow_write(&self[2])?;
50        Ok(())
51    }
52
53    fn wow_size(&self) -> usize {
54        0_u32.wow_size() * 3
55    }
56}
57
58impl WowHeaderR for i32 {
59    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
60        Ok(reader.read_i32::<LittleEndian>()?)
61    }
62}
63impl WowHeaderW for i32 {
64    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
65        writer.write_i32::<LittleEndian>(*self)?;
66        Ok(())
67    }
68
69    fn wow_size(&self) -> usize {
70        4
71    }
72}
73
74impl WowHeaderR for i16 {
75    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
76        Ok(reader.read_i16::<LittleEndian>()?)
77    }
78}
79impl WowHeaderW for i16 {
80    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
81        writer.write_i16::<LittleEndian>(*self)?;
82        Ok(())
83    }
84
85    fn wow_size(&self) -> usize {
86        2
87    }
88}
89
90impl WowHeaderR for [i16; 2] {
91    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
92        Ok([reader.wow_read()?, reader.wow_read()?])
93    }
94}
95impl WowHeaderW for [i16; 2] {
96    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
97        writer.wow_write(&self[0])?;
98        writer.wow_write(&self[1])?;
99        Ok(())
100    }
101
102    fn wow_size(&self) -> usize {
103        0_i16.wow_size() * 2
104    }
105}
106
107impl WowHeaderR for u16 {
108    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
109        Ok(reader.read_u16::<LittleEndian>()?)
110    }
111}
112impl WowHeaderW for u16 {
113    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
114        writer.write_u16::<LittleEndian>(*self)?;
115        Ok(())
116    }
117
118    fn wow_size(&self) -> usize {
119        2
120    }
121}
122
123impl WowHeaderR for [u16; 3] {
124    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
125        Ok([reader.wow_read()?, reader.wow_read()?, reader.wow_read()?])
126    }
127}
128impl WowHeaderW for [u16; 3] {
129    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
130        writer.wow_write(&self[0])?;
131        writer.wow_write(&self[1])?;
132        writer.wow_write(&self[2])?;
133        Ok(())
134    }
135
136    fn wow_size(&self) -> usize {
137        0_u16.wow_size() * 3
138    }
139}
140
141impl WowHeaderR for u8 {
142    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
143        Ok(reader.read_u8()?)
144    }
145}
146impl WowHeaderW for u8 {
147    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
148        writer.write_u8(*self)?;
149        Ok(())
150    }
151
152    fn wow_size(&self) -> usize {
153        1
154    }
155}
156
157impl WowHeaderR for [u8; 2] {
158    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
159        Ok([reader.read_u8()?, reader.read_u8()?])
160    }
161}
162impl WowHeaderW for [u8; 2] {
163    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
164        for i in 0..2 {
165            writer.write_u8((*self)[i])?;
166        }
167        Ok(())
168    }
169
170    fn wow_size(&self) -> usize {
171        2
172    }
173}
174
175impl WowHeaderR for [u8; 4] {
176    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
177        Ok([
178            reader.read_u8()?,
179            reader.read_u8()?,
180            reader.read_u8()?,
181            reader.read_u8()?,
182        ])
183    }
184}
185impl WowHeaderW for [u8; 4] {
186    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
187        for i in 0..4 {
188            writer.write_u8((*self)[i])?;
189        }
190        Ok(())
191    }
192
193    fn wow_size(&self) -> usize {
194        4
195    }
196}
197
198impl WowHeaderR for i8 {
199    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
200        Ok(reader.read_i8()?)
201    }
202}
203impl WowHeaderW for i8 {
204    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
205        writer.write_i8(*self)?;
206        Ok(())
207    }
208
209    fn wow_size(&self) -> usize {
210        1
211    }
212}
213
214impl WowHeaderR for u64 {
215    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
216        Ok(reader.read_u64::<LittleEndian>()?)
217    }
218}
219impl WowHeaderW for u64 {
220    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
221        writer.write_u64::<LittleEndian>(*self)?;
222        Ok(())
223    }
224
225    fn wow_size(&self) -> usize {
226        8
227    }
228}
229
230impl WowHeaderR for i64 {
231    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
232        Ok(reader.read_i64::<LittleEndian>()?)
233    }
234}
235impl WowHeaderW for i64 {
236    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
237        writer.write_i64::<LittleEndian>(*self)?;
238        Ok(())
239    }
240
241    fn wow_size(&self) -> usize {
242        8
243    }
244}
245
246impl WowHeaderR for f32 {
247    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
248        Ok(reader.read_f32::<LittleEndian>()?)
249    }
250}
251impl WowHeaderW for f32 {
252    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
253        writer.write_f32::<LittleEndian>(*self)?;
254        Ok(())
255    }
256
257    fn wow_size(&self) -> usize {
258        4
259    }
260}
261
262impl WowHeaderR for [f32; 3] {
263    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
264        Ok([reader.wow_read()?, reader.wow_read()?, reader.wow_read()?])
265    }
266}
267impl WowHeaderW for [f32; 3] {
268    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
269        writer.wow_write(&self[0])?;
270        writer.wow_write(&self[1])?;
271        writer.wow_write(&self[2])?;
272        Ok(())
273    }
274
275    fn wow_size(&self) -> usize {
276        0_f32.wow_size() * 3
277    }
278}
279
280impl WowHeaderW for String {
281    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
282        writer.wow_write(self)?;
283        // write null terminator
284        writer.wow_write(&0_u8)?;
285        Ok(())
286    }
287
288    fn wow_size(&self) -> usize {
289        self.len() + 1
290    }
291}
292
293impl WowString for String {
294    fn from_wow_char_array<R: Read + Seek>(
295        reader: &mut R,
296        wow_string: WowCharArray,
297    ) -> Result<String> {
298        if wow_string.count == 0 {
299            return Ok("".into());
300        }
301
302        let bytes = wow_string.wow_read_to_vec(reader)?;
303        let str_end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len());
304        Ok(String::from_utf8_lossy(&bytes[..str_end]).to_string())
305    }
306
307    fn write_wow_char_array<W: Write + Seek>(&self, writer: &mut W) -> Result<WowCharArray> {
308        let offset = writer.stream_position()?;
309        writer.wow_write(self)?;
310        Ok(WowCharArray::new(self.wow_size() as u32, offset as u32))
311    }
312}
313
314impl WowDataR<WowCharArray> for String {
315    fn new_from_header<R: Read + Seek>(reader: &mut R, header: &WowCharArray) -> Result<Self> {
316        String::from_wow_char_array(reader, header.clone())
317    }
318}
319
320impl<T: WowHeaderR + WowHeaderW> WowVec<T> for Vec<T> {
321    /// Write vector data to `writer` and return a `WowArray<T>`. The offset property
322    /// is set from the current writer position.
323    fn wow_write<W: Write + Seek>(&self, writer: &mut W) -> Result<WowArray<T>> {
324        let offset = writer.stream_position()?;
325        for item in self {
326            writer.wow_write(item)?
327        }
328        Ok(WowArray::<T>::new(self.len() as u32, offset as u32))
329    }
330}
331
332impl<T> WowDataR<WowArray<T>> for Vec<T>
333where
334    T: WowHeaderR + WowHeaderW,
335{
336    fn new_from_header<R: Read + Seek>(reader: &mut R, header: &WowArray<T>) -> Result<Self> {
337        header.wow_read_to_vec(reader)
338    }
339}