1use std::convert::Infallible;
2
3use crate::byte_handler::{ByteHandlerError, FromByteHandler};
4
5#[derive(Clone, Copy)]
8pub struct Hair {
9 hair_type: HairType,
11 hair_color: HairColor,
13 is_flipped: bool,
15}
16
17impl Hair {
18 pub fn new(hair_type: HairType, hair_color: HairColor, is_flipped: bool) -> Self {
26 Self {
27 hair_type,
28 hair_color,
29 is_flipped,
30 }
31 }
32
33 pub fn hair_type(&self) -> HairType {
35 self.hair_type
36 }
37
38 pub fn hair_color(&self) -> HairColor {
40 self.hair_color
41 }
42
43 pub fn is_flipped(&self) -> bool {
45 self.is_flipped
46 }
47
48 pub fn set_hair_type(&mut self, hair_type: HairType) {
50 self.hair_type = hair_type;
51 }
52
53 pub fn set_hair_color(&mut self, hair_color: HairColor) {
55 self.hair_color = hair_color;
56 }
57
58 pub fn set_is_flipped(&mut self, is_flipped: bool) {
60 self.is_flipped = is_flipped;
61 }
62}
63
64#[derive(thiserror::Error, Debug)]
66pub enum HairError {
67 #[error("Type is invalid")]
69 TypeInvalid,
70 #[error("Color is invalid")]
72 ColorInvalid,
73 #[error("ByteHandler Error: {0}")]
75 ByteHandlerError(#[from] ByteHandlerError),
76 #[error("")]
78 Infallible(#[from] Infallible),
79}
80
81impl FromByteHandler for Hair {
86 type Err = HairError;
87 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
88 where
89 T: TryInto<crate::byte_handler::ByteHandler>,
90 Self::Err: From<T::Error>,
91 {
92 let mut handler = handler.try_into()?;
93 handler.shift_right(1);
94 Ok(Self {
95 is_flipped: handler.read_bool(12),
96 hair_type: HairType::try_from(handler.copy_byte(0))
97 .map_err(|_| HairError::TypeInvalid)?,
98 hair_color: HairColor::try_from(handler.copy_byte(1) >> 5)
99 .map_err(|_| HairError::ColorInvalid)?,
100 })
101 }
102}
103
104#[derive(Clone, Copy, PartialEq, Debug)]
108pub enum HairColor {
109 Black,
110 Chocolate,
111 PhilippineBrown,
112 Walnut,
113 Gray,
114 Pineapple,
115 Grizzly,
116 Blond,
117}
118
119impl TryFrom<u8> for HairColor {
123 type Error = ();
124 fn try_from(value: u8) -> Result<Self, Self::Error> {
125 match value {
126 0x00 => Ok(Self::Black),
127 0x01 => Ok(Self::Chocolate),
128 0x02 => Ok(Self::PhilippineBrown),
129 0x03 => Ok(Self::Walnut),
130 0x04 => Ok(Self::Gray),
131 0x05 => Ok(Self::Pineapple),
132 0x06 => Ok(Self::Grizzly),
133 0x07 => Ok(Self::Blond),
134 _ => Err(()),
135 }
136 }
137}
138
139impl From<HairColor> for u8 {
141 fn from(value: HairColor) -> Self {
142 match value {
143 HairColor::Black => 0x00,
144 HairColor::Chocolate => 0x01,
145 HairColor::PhilippineBrown => 0x02,
146 HairColor::Walnut => 0x03,
147 HairColor::Gray => 0x04,
148 HairColor::Pineapple => 0x05,
149 HairColor::Grizzly => 0x06,
150 HairColor::Blond => 0x07,
151 }
152 }
153}
154
155#[derive(Clone, Copy, PartialEq, Debug)]
161pub enum HairType {
162 NormalLong,
163 NormalMedium,
164 FrontLock,
165 PartingExtraLong,
166 MilitaryParting,
167 PartingExtraLongCurved,
168 ShortUnknown3,
169 PeaksSquared,
170 ShortUnknown5,
171 Peaks,
172 PeaksRounded,
173 PeaksLongBottom,
174 NormalLongBottom,
175 NormalShort,
176 NormalExtraLong,
177 PartingLong,
178 PartingMiddleLong,
179 PartingSquared,
180 LongRounded,
181 PartingLongBottom,
182 PartingShort,
183 PartingFrontPeaks,
184 NormalUnknown1,
185 PeaksSide,
186 PartingPeaks,
187 PeaksTop,
188 DreadLocks,
189 Short,
190 ShortUnknown4,
191 Afro,
192 Military,
193 NoneTop,
194 ShortUnknown6,
195 None,
196 Caps,
197 Beanie,
198 LongUnknown1,
199 LongUnknown40,
200 LongUnknown38,
201 LongUnknown60,
202 LongUnknown16,
203 LongUnknown36,
204 LongUnknown56,
205 PartingFrontTwoLongBackPonyTails,
206 LongUnknown31,
207 LongUnknown20,
208 LongUnknown15,
209 LongUnknown52,
210 LongUnknown7,
211 LongUnknown23,
212 PartingExtraLongRounded,
213 LongUnknown3,
214 LongUnknown11,
215 LongUnknown12,
216 LongUnknown29,
217 LongUnknown27,
218 LongUnknown17,
219 LongUnknown39,
220 LongUnknown24,
221 LongUnknown25,
222 LongUnknown61,
223 LongUnknown2,
224 StrandsTwoShortSidedPonyTails,
225 TwoFrontStrandsLongBackPonyTail,
226 LongUnknown65,
227 LongUnknown63,
228 ShortFrontTwoBackPonyTails,
229 LongUnknown43,
230 LongUnknown47,
231 LongUnknown44,
232 LongUnknown53,
233 LongUnknown51,
234}
235
236impl TryFrom<u8> for HairType {
240 type Error = ();
241 fn try_from(value: u8) -> Result<Self, Self::Error> {
242 match value {
243 0x21 => Ok(Self::NormalLong),
244 0x28 => Ok(Self::NormalMedium),
245 0x33 => Ok(Self::FrontLock),
246 0x2c => Ok(Self::PartingExtraLong),
247 0x27 => Ok(Self::MilitaryParting),
248 0x46 => Ok(Self::PartingExtraLongCurved),
249 0x2d => Ok(Self::ShortUnknown3),
250 0x31 => Ok(Self::PeaksSquared),
251 0x3b => Ok(Self::ShortUnknown5),
252 0x38 => Ok(Self::Peaks),
253 0x44 => Ok(Self::PeaksRounded),
254 0x1f => Ok(Self::PeaksLongBottom),
255 0x20 => Ok(Self::NormalLongBottom),
256 0x2f => Ok(Self::NormalShort),
257 0x25 => Ok(Self::NormalExtraLong),
258 0x30 => Ok(Self::PartingLong),
259 0x42 => Ok(Self::PartingMiddleLong),
260 0x34 => Ok(Self::PartingSquared),
261 0x3a => Ok(Self::LongRounded),
262 0x32 => Ok(Self::PartingLongBottom),
263 0x37 => Ok(Self::PartingShort),
264 0x40 => Ok(Self::PartingFrontPeaks),
265 0x3c => Ok(Self::NormalUnknown1),
266 0x3e => Ok(Self::PeaksSide),
267 0x2b => Ok(Self::PartingPeaks),
268 0x26 => Ok(Self::PeaksTop),
269 0x2a => Ok(Self::DreadLocks),
270 0x17 => Ok(Self::Short),
271 0x43 => Ok(Self::ShortUnknown4),
272 0x36 => Ok(Self::Afro),
273 0x24 => Ok(Self::Military),
274 0x29 => Ok(Self::NoneTop),
275 0x41 => Ok(Self::ShortUnknown6),
276 0x1e => Ok(Self::None),
277 0x39 => Ok(Self::Caps),
278 0x22 => Ok(Self::Beanie),
279 0x0c => Ok(Self::LongUnknown1),
280 0x0d => Ok(Self::LongUnknown40),
281 0x45 => Ok(Self::LongUnknown38),
282 0x1a => Ok(Self::LongUnknown60),
283 0x04 => Ok(Self::LongUnknown16),
284 0x19 => Ok(Self::LongUnknown36),
285 0x01 => Ok(Self::LongUnknown56),
286 0x13 => Ok(Self::PartingFrontTwoLongBackPonyTails),
287 0x05 => Ok(Self::LongUnknown31),
288 0x08 => Ok(Self::LongUnknown20),
289 0x1b => Ok(Self::LongUnknown15),
290 0x07 => Ok(Self::LongUnknown52),
291 0x0e => Ok(Self::LongUnknown7),
292 0x03 => Ok(Self::LongUnknown23),
293 0x16 => Ok(Self::PartingExtraLongRounded),
294 0x0a => Ok(Self::LongUnknown3),
295 0x06 => Ok(Self::LongUnknown11),
296 0x14 => Ok(Self::LongUnknown12),
297 0x0b => Ok(Self::LongUnknown29),
298 0x3f => Ok(Self::LongUnknown27),
299 0x11 => Ok(Self::LongUnknown17),
300 0x23 => Ok(Self::LongUnknown39),
301 0x15 => Ok(Self::LongUnknown24),
302 0x00 => Ok(Self::LongUnknown25),
303 0x3d => Ok(Self::LongUnknown61),
304 0x10 => Ok(Self::LongUnknown2),
305 0x2e => Ok(Self::StrandsTwoShortSidedPonyTails),
306 0x09 => Ok(Self::TwoFrontStrandsLongBackPonyTail),
307 0x12 => Ok(Self::LongUnknown65),
308 0x02 => Ok(Self::LongUnknown63),
309 0x1c => Ok(Self::ShortFrontTwoBackPonyTails),
310 0x35 => Ok(Self::LongUnknown43),
311 0x47 => Ok(Self::LongUnknown47),
312 0x18 => Ok(Self::LongUnknown44),
313 0x0f => Ok(Self::LongUnknown53),
314 0x1d => Ok(Self::LongUnknown51),
315 _ => Err(()),
316 }
317 }
318}
319
320impl From<HairType> for u8 {
322 fn from(value: HairType) -> Self {
323 match value {
324 HairType::NormalLong => 0x21,
325 HairType::NormalMedium => 0x28,
326 HairType::FrontLock => 0x33,
327 HairType::PartingExtraLong => 0x2c,
328 HairType::MilitaryParting => 0x27,
329 HairType::PartingExtraLongCurved => 0x46,
330 HairType::ShortUnknown3 => 0x2d,
331 HairType::PeaksSquared => 0x31,
332 HairType::ShortUnknown5 => 0x3b,
333 HairType::Peaks => 0x38,
334 HairType::PeaksRounded => 0x44,
335 HairType::PeaksLongBottom => 0x1f,
336 HairType::NormalLongBottom => 0x20,
337 HairType::NormalShort => 0x2f,
338 HairType::NormalExtraLong => 0x25,
339 HairType::PartingLong => 0x30,
340 HairType::PartingMiddleLong => 0x42,
341 HairType::PartingSquared => 0x34,
342 HairType::LongRounded => 0x3a,
343 HairType::PartingLongBottom => 0x32,
344 HairType::PartingShort => 0x37,
345 HairType::PartingFrontPeaks => 0x40,
346 HairType::NormalUnknown1 => 0x3c,
347 HairType::PeaksSide => 0x3e,
348 HairType::PartingPeaks => 0x2b,
349 HairType::PeaksTop => 0x26,
350 HairType::DreadLocks => 0x2a,
351 HairType::Short => 0x17,
352 HairType::ShortUnknown4 => 0x43,
353 HairType::Afro => 0x36,
354 HairType::Military => 0x24,
355 HairType::NoneTop => 0x29,
356 HairType::ShortUnknown6 => 0x41,
357 HairType::None => 0x1e,
358 HairType::Caps => 0x39,
359 HairType::Beanie => 0x22,
360 HairType::LongUnknown1 => 0x0c,
361 HairType::LongUnknown40 => 0x0d,
362 HairType::LongUnknown38 => 0x45,
363 HairType::LongUnknown60 => 0x1a,
364 HairType::LongUnknown16 => 0x04,
365 HairType::LongUnknown36 => 0x19,
366 HairType::LongUnknown56 => 0x01,
367 HairType::PartingFrontTwoLongBackPonyTails => 0x13,
368 HairType::LongUnknown31 => 0x05,
369 HairType::LongUnknown20 => 0x08,
370 HairType::LongUnknown15 => 0x1b,
371 HairType::LongUnknown52 => 0x07,
372 HairType::LongUnknown7 => 0x0e,
373 HairType::LongUnknown23 => 0x03,
374 HairType::PartingExtraLongRounded => 0x16,
375 HairType::LongUnknown3 => 0x0a,
376 HairType::LongUnknown11 => 0x06,
377 HairType::LongUnknown12 => 0x14,
378 HairType::LongUnknown29 => 0x0b,
379 HairType::LongUnknown27 => 0x3f,
380 HairType::LongUnknown17 => 0x11,
381 HairType::LongUnknown39 => 0x23,
382 HairType::LongUnknown24 => 0x15,
383 HairType::LongUnknown25 => 0x00,
384 HairType::LongUnknown61 => 0x3d,
385 HairType::LongUnknown2 => 0x10,
386 HairType::StrandsTwoShortSidedPonyTails => 0x2e,
387 HairType::TwoFrontStrandsLongBackPonyTail => 0x09,
388 HairType::LongUnknown65 => 0x12,
389 HairType::LongUnknown63 => 0x02,
390 HairType::ShortFrontTwoBackPonyTails => 0x1c,
391 HairType::LongUnknown43 => 0x35,
392 HairType::LongUnknown47 => 0x47,
393 HairType::LongUnknown44 => 0x18,
394 HairType::LongUnknown53 => 0x0f,
395 HairType::LongUnknown51 => 0x1d,
396 }
397 }
398}