1use std::convert::Infallible;
2
3use crate::byte_handler::{ByteHandlerError, FromByteHandler};
4
5#[derive(Clone, Copy)]
10pub struct Eyes {
11 rotation: u8,
13 size: u8,
15 x: u8,
17 y: u8,
19 eye_color: EyeColor,
21 eye_type: EyeType,
23}
24
25impl Eyes {
26 pub fn new(
44 rotation: u8,
45 size: u8,
46 x: u8,
47 y: u8,
48 eye_color: EyeColor,
49 eye_type: EyeType,
50 ) -> Result<Self, EyesError> {
51 if size > 7 {
52 return Err(EyesError::SizeInvalid);
53 }
54 if rotation > 7 {
55 return Err(EyesError::RotationInvalid);
56 }
57 if y > 18 {
58 return Err(EyesError::YInvalid);
59 }
60 if x > 12 {
61 return Err(EyesError::XInvalid);
62 }
63
64 Ok(Self {
65 rotation,
66 size,
67 x,
68 y,
69 eye_color,
70 eye_type,
71 })
72 }
73
74 pub fn rotation(&self) -> u8 {
76 self.rotation
77 }
78
79 pub fn size(&self) -> u8 {
81 self.size
82 }
83
84 pub fn x(&self) -> u8 {
86 self.x
87 }
88
89 pub fn y(&self) -> u8 {
91 self.y
92 }
93
94 pub fn eye_color(&self) -> EyeColor {
96 self.eye_color
97 }
98
99 pub fn eye_type(&self) -> EyeType {
101 self.eye_type
102 }
103
104 pub fn set_rotation(&mut self, rotation: u8) -> Result<(), EyesError> {
110 if rotation > 7 {
111 return Err(EyesError::RotationInvalid);
112 }
113 self.rotation = rotation;
114 Ok(())
115 }
116
117 pub fn set_size(&mut self, size: u8) -> Result<(), EyesError> {
123 if size > 7 {
124 return Err(EyesError::SizeInvalid);
125 }
126 self.size = size;
127 Ok(())
128 }
129
130 pub fn set_x(&mut self, x: u8) -> Result<(), EyesError> {
136 if x > 12 {
137 return Err(EyesError::XInvalid);
138 }
139 self.x = x;
140 Ok(())
141 }
142
143 pub fn set_y(&mut self, y: u8) -> Result<(), EyesError> {
149 if y > 18 {
150 return Err(EyesError::YInvalid);
151 }
152 self.y = y;
153 Ok(())
154 }
155
156 pub fn set_eye_color(&mut self, eye_color: EyeColor) {
158 self.eye_color = eye_color;
159 }
160
161 pub fn set_eye_type(&mut self, eye_type: EyeType) {
163 self.eye_type = eye_type;
164 }
165}
166
167#[derive(thiserror::Error, Debug)]
169pub enum EyesError {
170 #[error("Type is invalid")]
172 TypeInvalid,
173 #[error("Color is invalid")]
175 ColorInvalid,
176 #[error("Rotation is invalid")]
178 RotationInvalid,
179 #[error("Size is invalid")]
181 SizeInvalid,
182 #[error("Y position is invalid")]
184 YInvalid,
185 #[error("X position is invalid")]
187 XInvalid,
188 #[error("ByteHandler Error: {0}")]
190 ByteHandlerError(#[from] ByteHandlerError),
191 #[error("")]
193 Infallible(#[from] Infallible),
194}
195
196impl FromByteHandler for Eyes {
201 type Err = EyesError;
202 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
203 where
204 T: TryInto<crate::byte_handler::ByteHandler>,
205 Self::Err: From<T::Error>,
206 {
207 let mut handler = handler.try_into()?;
208
209 let eye_type =
210 EyeType::try_from(handler.copy_byte(0) >> 2).map_err(|_| EyesError::TypeInvalid)?;
211 let eye_color =
212 EyeColor::try_from(handler.copy_byte(2) >> 5).map_err(|_| EyesError::ColorInvalid)?;
213 let y = handler.copy_byte(1) & 0x1F;
214 handler.shift_right(5);
215 let rotation = handler.copy_byte(1) & 0x1F;
216 let x = handler.copy_byte(3) & 0x0F;
217 let size = handler.copy_byte(3) >> 4;
218
219 Self::new(rotation, size, x, y, eye_color, eye_type)
220 }
221}
222
223#[derive(Clone, Copy, PartialEq, Debug)]
225pub enum EyeColor {
226 Black,
227 Gray,
228 Brown,
229 Hazel,
230 Blue,
231 Green,
232}
233
234impl TryFrom<u8> for EyeColor {
238 type Error = ();
239 fn try_from(value: u8) -> Result<Self, Self::Error> {
240 match value {
241 0x00 => Ok(Self::Black),
242 0x01 => Ok(Self::Gray),
243 0x02 => Ok(Self::Brown),
244 0x03 => Ok(Self::Hazel),
245 0x04 => Ok(Self::Blue),
246 0x05 => Ok(Self::Green),
247 _ => Err(()),
248 }
249 }
250}
251
252impl From<EyeColor> for u8 {
254 fn from(value: EyeColor) -> Self {
255 match value {
256 EyeColor::Black => 0x00,
257 EyeColor::Gray => 0x01,
258 EyeColor::Brown => 0x02,
259 EyeColor::Hazel => 0x03,
260 EyeColor::Blue => 0x04,
261 EyeColor::Green => 0x05,
262 }
263 }
264}
265
266#[derive(Clone, Copy, PartialEq, Debug)]
268pub enum EyeType {
269 Normal,
270 NormalLash,
271 WhiteLash,
272 WhiteNoBottom,
273 OvalAngledWhite,
274 AngryWhite,
275 DotLashType1,
276 Line,
277 DotLine,
278 OvalWhite,
279 RoundedWhite,
280 NormalShadow,
281 CircleWhite,
282 Circle,
283 CircleWhiteStroke,
284 NormalOvalNoBottom,
285 NormalOvalLarge,
286 NormalRoundedNoBottom,
287 SmallLash,
288 Small,
289 TwoSmall,
290 NormalLongLash,
291 WhiteTwoLashes,
292 WhiteThreeLashes,
293 DotAngry,
294 DotAngled,
295 Oval,
296 SmallWhite,
297 WhiteAngledNoBottom,
298 WhiteAngledNoLeft,
299 SmallWhiteTwoLashes,
300 LeafWhiteLash,
301 WhiteLargeNoBottom,
302 Dot,
303 DotLashType2,
304 DotThreeLashes,
305 WhiteOvalTop,
306 WhiteOvalBottom,
307 WhiteOvalBottomFlat,
308 WhiteOvalTwoLashes,
309 WhiteOvalThreeLashes,
310 WhiteOvalNoBottomTwoLashes,
311 DotWhite,
312 WhiteOvalTopFlat,
313 WhiteThinLeaf,
314 StarThreeLashes,
315 LineTwoLashes,
316 CrowsFeet,
317}
318
319impl TryFrom<u8> for EyeType {
323 type Error = ();
324 fn try_from(value: u8) -> Result<Self, Self::Error> {
325 match value {
326 0x02 => Ok(Self::Normal),
327 0x04 => Ok(Self::NormalLash),
328 0x00 => Ok(Self::WhiteLash),
329 0x08 => Ok(Self::WhiteNoBottom),
330 0x27 => Ok(Self::OvalAngledWhite),
331 0x11 => Ok(Self::AngryWhite),
332 0x01 => Ok(Self::DotLashType1),
333 0x1A => Ok(Self::Line),
334 0x10 => Ok(Self::DotLine),
335 0x0F => Ok(Self::OvalWhite),
336 0x1B => Ok(Self::RoundedWhite),
337 0x14 => Ok(Self::NormalShadow),
338 0x21 => Ok(Self::CircleWhite),
339 0x0B => Ok(Self::Circle),
340 0x13 => Ok(Self::CircleWhiteStroke),
341 0x20 => Ok(Self::NormalOvalNoBottom),
342 0x09 => Ok(Self::NormalOvalLarge),
343 0x0C => Ok(Self::NormalRoundedNoBottom),
344 0x17 => Ok(Self::SmallLash),
345 0x22 => Ok(Self::Small),
346 0x15 => Ok(Self::TwoSmall),
347 0x19 => Ok(Self::NormalLongLash),
348 0x28 => Ok(Self::WhiteTwoLashes),
349 0x23 => Ok(Self::WhiteThreeLashes),
350 0x05 => Ok(Self::DotAngry),
351 0x29 => Ok(Self::DotAngled),
352 0x0D => Ok(Self::Oval),
353 0x24 => Ok(Self::SmallWhite),
354 0x25 => Ok(Self::WhiteAngledNoBottom),
355 0x06 => Ok(Self::WhiteAngledNoLeft),
356 0x18 => Ok(Self::SmallWhiteTwoLashes),
357 0x1E => Ok(Self::LeafWhiteLash),
358 0x1F => Ok(Self::WhiteLargeNoBottom),
359 0x12 => Ok(Self::Dot),
360 0x1C => Ok(Self::DotLashType2),
361 0x2E => Ok(Self::DotThreeLashes),
362 0x07 => Ok(Self::WhiteOvalTop),
363 0x2C => Ok(Self::WhiteOvalBottom),
364 0x26 => Ok(Self::WhiteOvalBottomFlat),
365 0x2A => Ok(Self::WhiteOvalTwoLashes),
366 0x2D => Ok(Self::WhiteOvalThreeLashes),
367 0x1D => Ok(Self::WhiteOvalNoBottomTwoLashes),
368 0x03 => Ok(Self::DotWhite),
369 0x2B => Ok(Self::WhiteOvalTopFlat),
370 0x16 => Ok(Self::WhiteThinLeaf),
371 0x0A => Ok(Self::StarThreeLashes),
372 0x0E => Ok(Self::LineTwoLashes),
373 0x2F => Ok(Self::CrowsFeet),
374 _ => Err(()),
375 }
376 }
377}
378
379impl From<EyeType> for u8 {
381 fn from(value: EyeType) -> Self {
382 match value {
383 EyeType::Normal => 0x02,
384 EyeType::NormalLash => 0x04,
385 EyeType::WhiteLash => 0x00,
386 EyeType::WhiteNoBottom => 0x08,
387 EyeType::OvalAngledWhite => 0x27,
388 EyeType::AngryWhite => 0x11,
389 EyeType::DotLashType1 => 0x01,
390 EyeType::Line => 0x1A,
391 EyeType::DotLine => 0x10,
392 EyeType::OvalWhite => 0x0F,
393 EyeType::RoundedWhite => 0x1B,
394 EyeType::NormalShadow => 0x14,
395 EyeType::CircleWhite => 0x21,
396 EyeType::Circle => 0x0B,
397 EyeType::CircleWhiteStroke => 0x13,
398 EyeType::NormalOvalNoBottom => 0x20,
399 EyeType::NormalOvalLarge => 0x09,
400 EyeType::NormalRoundedNoBottom => 0x0C,
401 EyeType::SmallLash => 0x17,
402 EyeType::Small => 0x22,
403 EyeType::TwoSmall => 0x15,
404 EyeType::NormalLongLash => 0x19,
405 EyeType::WhiteTwoLashes => 0x28,
406 EyeType::WhiteThreeLashes => 0x23,
407 EyeType::DotAngry => 0x05,
408 EyeType::DotAngled => 0x29,
409 EyeType::Oval => 0x0D,
410 EyeType::SmallWhite => 0x24,
411 EyeType::WhiteAngledNoBottom => 0x25,
412 EyeType::WhiteAngledNoLeft => 0x06,
413 EyeType::SmallWhiteTwoLashes => 0x18,
414 EyeType::LeafWhiteLash => 0x1E,
415 EyeType::WhiteLargeNoBottom => 0x1F,
416 EyeType::Dot => 0x12,
417 EyeType::DotLashType2 => 0x1C,
418 EyeType::DotThreeLashes => 0x2E,
419 EyeType::WhiteOvalTop => 0x07,
420 EyeType::WhiteOvalBottom => 0x2C,
421 EyeType::WhiteOvalBottomFlat => 0x26,
422 EyeType::WhiteOvalTwoLashes => 0x2A,
423 EyeType::WhiteOvalThreeLashes => 0x2D,
424 EyeType::WhiteOvalNoBottomTwoLashes => 0x1D,
425 EyeType::DotWhite => 0x03,
426 EyeType::WhiteOvalTopFlat => 0x2B,
427 EyeType::WhiteThinLeaf => 0x16,
428 EyeType::StarThreeLashes => 0x0A,
429 EyeType::LineTwoLashes => 0x0E,
430 EyeType::CrowsFeet => 0x2F,
431 }
432 }
433}