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 f32 {
215    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
216        Ok(reader.read_f32::<LittleEndian>()?)
217    }
218}
219impl WowHeaderW for f32 {
220    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
221        writer.write_f32::<LittleEndian>(*self)?;
222        Ok(())
223    }
224
225    fn wow_size(&self) -> usize {
226        4
227    }
228}
229
230impl WowHeaderR for [f32; 3] {
231    fn wow_read<R: Read + Seek>(reader: &mut R) -> Result<Self> {
232        Ok([reader.wow_read()?, reader.wow_read()?, reader.wow_read()?])
233    }
234}
235impl WowHeaderW for [f32; 3] {
236    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
237        writer.wow_write(&self[0])?;
238        writer.wow_write(&self[1])?;
239        writer.wow_write(&self[2])?;
240        Ok(())
241    }
242
243    fn wow_size(&self) -> usize {
244        0_f32.wow_size() * 3
245    }
246}
247
248impl WowHeaderW for String {
249    fn wow_write<W: Write>(&self, writer: &mut W) -> Result<()> {
250        writer.wow_write(self)?;
251        // write null terminator
252        writer.wow_write(&0_u8)?;
253        Ok(())
254    }
255
256    fn wow_size(&self) -> usize {
257        self.len() + 1
258    }
259}
260
261impl WowString for String {
262    fn from_wow_char_array<R: Read + Seek>(
263        reader: &mut R,
264        wow_string: WowCharArray,
265    ) -> Result<String> {
266        if wow_string.count == 0 {
267            return Ok("".into());
268        }
269
270        let bytes = wow_string.wow_read_to_vec(reader)?;
271        let str_end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len());
272        Ok(String::from_utf8_lossy(&bytes[..str_end]).to_string())
273    }
274
275    fn write_wow_char_array<W: Write + Seek>(&self, writer: &mut W) -> Result<WowCharArray> {
276        let offset = writer.stream_position()?;
277        writer.wow_write(self)?;
278        Ok(WowCharArray::new(self.wow_size() as u32, offset as u32))
279    }
280}
281
282impl WowDataR<WowCharArray> for String {
283    fn new_from_header<R: Read + Seek>(reader: &mut R, header: &WowCharArray) -> Result<Self> {
284        String::from_wow_char_array(reader, header.clone())
285    }
286}
287
288impl<T: WowHeaderR + WowHeaderW> WowVec<T> for Vec<T> {
289    /// Write vector data to `writer` and return a `WowArray<T>`. The offset property
290    /// is set from the current writer position.
291    fn wow_write<W: Write + Seek>(&self, writer: &mut W) -> Result<WowArray<T>> {
292        let offset = writer.stream_position()?;
293        for item in self {
294            writer.wow_write(item)?
295        }
296        Ok(WowArray::<T>::new(self.len() as u32, offset as u32))
297    }
298}
299
300impl<T> WowDataR<WowArray<T>> for Vec<T>
301where
302    T: WowHeaderR + WowHeaderW,
303{
304    fn new_from_header<R: Read + Seek>(reader: &mut R, header: &WowArray<T>) -> Result<Self> {
305        header.wow_read_to_vec(reader)
306    }
307}