rkg_utils/header/mii/
facial_hair.rs1use std::convert::Infallible;
2
3use crate::{
4 byte_handler::{ByteHandlerError, FromByteHandler},
5 header::mii::hair::HairColor,
6};
7
8#[derive(Clone, Copy)]
11pub struct FacialHair {
12 beard_type: BeardType,
14 mustache_type: MustacheType,
16 color: HairColor,
18 mustache_size: u8,
20 mustache_y: u8,
22}
23
24impl FacialHair {
25 pub fn new(
40 beard_type: BeardType,
41 mustache_type: MustacheType,
42 color: HairColor,
43 mustache_size: u8,
44 mustache_y: u8,
45 ) -> Result<Self, FacialHairError> {
46 if mustache_size > 8 {
47 return Err(FacialHairError::SizeInvalid);
48 }
49 if mustache_y > 16 {
50 return Err(FacialHairError::YInvalid);
51 }
52
53 Ok(Self {
54 beard_type,
55 mustache_type,
56 color,
57 mustache_size,
58 mustache_y,
59 })
60 }
61
62 pub fn beard_type(&self) -> BeardType {
64 self.beard_type
65 }
66
67 pub fn mustache_type(&self) -> MustacheType {
69 self.mustache_type
70 }
71
72 pub fn color(&self) -> HairColor {
74 self.color
75 }
76
77 pub fn mustache_size(&self) -> u8 {
79 self.mustache_size
80 }
81
82 pub fn mustache_y(&self) -> u8 {
84 self.mustache_y
85 }
86
87 pub fn set_beard_type(&mut self, beard_type: BeardType) {
89 self.beard_type = beard_type;
90 }
91
92 pub fn set_mustache_type(&mut self, mustache_type: MustacheType) {
94 self.mustache_type = mustache_type;
95 }
96
97 pub fn set_color(&mut self, color: HairColor) {
99 self.color = color;
100 }
101
102 pub fn set_mustache_size(&mut self, mustache_size: u8) -> Result<(), FacialHairError> {
108 if mustache_size > 8 {
109 return Err(FacialHairError::SizeInvalid);
110 }
111 self.mustache_size = mustache_size;
112 Ok(())
113 }
114
115 pub fn set_mustache_y(&mut self, mustache_y: u8) -> Result<(), FacialHairError> {
121 if mustache_y > 16 {
122 return Err(FacialHairError::YInvalid);
123 }
124 self.mustache_y = mustache_y;
125 Ok(())
126 }
127}
128
129impl FromByteHandler for FacialHair {
134 type Err = FacialHairError;
135 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
136 where
137 T: TryInto<crate::byte_handler::ByteHandler>,
138 Self::Err: From<T::Error>,
139 {
140 let mut handler = handler.try_into()?;
141 let mustache_y = handler.copy_byte(1) & 0x1F;
142 handler.shift_right(1);
143
144 let mustache_size = handler.copy_byte(1) >> 4;
145 let color = HairColor::try_from(handler.copy_byte(0) & 0x07)
146 .map_err(|_| FacialHairError::ColorInvalid)?;
147 let mustache_type = MustacheType::try_from(handler.copy_byte(0) >> 5)
148 .map_err(|_| FacialHairError::MustacheTypeInvalid)?;
149 let beard_type = BeardType::try_from((handler.copy_byte(0) >> 3) & 0x03)
150 .map_err(|_| FacialHairError::BeardTypeInvalid)?;
151
152 Self::new(beard_type, mustache_type, color, mustache_size, mustache_y)
153 }
154}
155
156#[derive(thiserror::Error, Debug)]
158pub enum FacialHairError {
159 #[error("Beard Type is invalid")]
161 BeardTypeInvalid,
162 #[error("Mustache Type is invalid")]
164 MustacheTypeInvalid,
165 #[error("Color is invalid")]
167 ColorInvalid,
168 #[error("Size is invalid")]
170 SizeInvalid,
171 #[error("Y position is invalid")]
173 YInvalid,
174 #[error("ByteHandler Error: {0}")]
176 ByteHandlerError(#[from] ByteHandlerError),
177 #[error("")]
179 Infallible(#[from] Infallible),
180}
181
182#[derive(Clone, Copy, PartialEq, Debug)]
184pub enum BeardType {
185 None,
187 Goatee,
189 GoateeLong,
191 LionsManeLong,
193}
194
195impl TryFrom<u8> for BeardType {
199 type Error = ();
200 fn try_from(value: u8) -> Result<Self, Self::Error> {
201 match value {
202 0 => Ok(Self::None),
203 1 => Ok(Self::Goatee),
204 2 => Ok(Self::GoateeLong),
205 3 => Ok(Self::LionsManeLong),
206 _ => Err(()),
207 }
208 }
209}
210
211impl From<BeardType> for u8 {
213 fn from(value: BeardType) -> Self {
214 match value {
215 BeardType::None => 0,
216 BeardType::Goatee => 1,
217 BeardType::GoateeLong => 2,
218 BeardType::LionsManeLong => 3,
219 }
220 }
221}
222
223#[derive(Clone, Copy, PartialEq, Debug)]
225pub enum MustacheType {
226 None,
228 Walrus,
230 Pencil,
232 Horseshoe,
234}
235
236impl TryFrom<u8> for MustacheType {
240 type Error = ();
241 fn try_from(value: u8) -> Result<Self, Self::Error> {
242 match value {
243 0 => Ok(Self::None),
244 1 => Ok(Self::Walrus),
245 2 => Ok(Self::Pencil),
246 3 => Ok(Self::Horseshoe),
247 _ => Err(()),
248 }
249 }
250}
251
252impl From<MustacheType> for u8 {
254 fn from(value: MustacheType) -> Self {
255 match value {
256 MustacheType::None => 0,
257 MustacheType::Walrus => 1,
258 MustacheType::Pencil => 2,
259 MustacheType::Horseshoe => 3,
260 }
261 }
262}