1use std::convert::Infallible;
2
3use crate::byte_handler::{ByteHandlerError, FromByteHandler};
4
5#[derive(Clone, Copy)]
8pub struct Lips {
9 y: u8,
11 size: u8,
13 lips_type: LipsType,
15 lips_color: LipsColor,
17}
18
19impl Lips {
20 pub fn new(
34 y: u8,
35 size: u8,
36 lips_type: LipsType,
37 lips_color: LipsColor,
38 ) -> Result<Self, LipsError> {
39 if y > 18 {
40 return Err(LipsError::YInvalid);
41 }
42 if size > 8 {
43 return Err(LipsError::SizeInvalid);
44 }
45 Ok(Self {
46 y,
47 size,
48 lips_type,
49 lips_color,
50 })
51 }
52
53 pub fn y(&self) -> u8 {
55 self.y
56 }
57
58 pub fn size(&self) -> u8 {
60 self.size
61 }
62
63 pub fn lips_type(&self) -> LipsType {
65 self.lips_type
66 }
67
68 pub fn lips_color(&self) -> LipsColor {
70 self.lips_color
71 }
72
73 pub fn set_y(&mut self, y: u8) -> Result<(), LipsError> {
79 if y > 18 {
80 return Err(LipsError::YInvalid);
81 }
82 self.y = y;
83 Ok(())
84 }
85
86 pub fn set_size(&mut self, size: u8) -> Result<(), LipsError> {
92 if size > 8 {
93 return Err(LipsError::SizeInvalid);
94 }
95 self.size = size;
96 Ok(())
97 }
98
99 pub fn set_lips_type(&mut self, lips_type: LipsType) {
101 self.lips_type = lips_type;
102 }
103
104 pub fn set_lips_color(&mut self, lips_color: LipsColor) {
106 self.lips_color = lips_color;
107 }
108}
109
110impl FromByteHandler for Lips {
115 type Err = LipsError;
116 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
117 where
118 T: TryInto<crate::byte_handler::ByteHandler>,
119 Self::Err: From<T::Error>,
120 {
121 let mut handler = handler.try_into()?;
122
123 let lips_type =
124 LipsType::try_from(handler.copy_byte(0) >> 3).map_err(|_| LipsError::TypeInvalid)?;
125 let y = handler.copy_byte(1) & 0x1F;
126 handler.shift_right(1);
127 let lips_color = LipsColor::try_from(handler.copy_byte(0) & 0x03)
128 .map_err(|_| LipsError::ColorInvalid)?;
129 let size = handler.copy_byte(1) >> 4;
130
131 Self::new(y, size, lips_type, lips_color)
132 }
133}
134
135#[derive(thiserror::Error, Debug)]
137pub enum LipsError {
138 #[error("Type is invalid")]
140 TypeInvalid,
141 #[error("Color is invalid")]
143 ColorInvalid,
144 #[error("Size is invalid")]
146 SizeInvalid,
147 #[error("Y position is invalid")]
149 YInvalid,
150 #[error("ByteHandler Error: {0}")]
152 ByteHandlerError(#[from] ByteHandlerError),
153 #[error("")]
155 Infallible(#[from] Infallible),
156}
157
158#[derive(Clone, Copy, PartialEq, Debug)]
160pub enum LipsColor {
161 Orange,
162 Red,
163 Pink,
164}
165
166impl TryFrom<u8> for LipsColor {
170 type Error = ();
171 fn try_from(value: u8) -> Result<Self, Self::Error> {
172 match value {
173 0 => Ok(Self::Orange),
174 1 => Ok(Self::Red),
175 2 => Ok(Self::Pink),
176 _ => Err(()),
177 }
178 }
179}
180
181impl From<LipsColor> for u8 {
183 fn from(value: LipsColor) -> Self {
184 match value {
185 LipsColor::Orange => 0,
186 LipsColor::Red => 1,
187 LipsColor::Pink => 2,
188 }
189 }
190}
191
192#[derive(Clone, Copy, PartialEq, Debug)]
194pub enum LipsType {
195 Neutral,
196 NeutralLips,
197 Smile,
198 SmileStroke,
199 SmileTeeth,
200 LipsSmall,
201 LipsLarge,
202 Wave,
203 WaveAngrySmall,
204 NeutralStrokeLarge,
205 TeethSurprised,
206 LipsExtraLarge,
207 LipsUp,
208 NeutralDown,
209 Surprised,
210 TeethMiddle,
211 NeutralStroke,
212 LipsExtraSmall,
213 Malicious,
214 LipsDual,
215 NeutralComma,
216 NeutralUp,
217 TeethLarge,
218 WaveAngry,
219}
220
221impl TryFrom<u8> for LipsType {
225 type Error = ();
226 fn try_from(value: u8) -> Result<Self, Self::Error> {
227 match value {
228 0x17 => Ok(Self::Neutral),
229 0x01 => Ok(Self::NeutralLips),
230 0x13 => Ok(Self::Smile),
231 0x15 => Ok(Self::SmileStroke),
232 0x16 => Ok(Self::SmileTeeth),
233 0x05 => Ok(Self::LipsSmall),
234 0x00 => Ok(Self::LipsLarge),
235 0x08 => Ok(Self::Wave),
236 0x0A => Ok(Self::WaveAngrySmall),
237 0x10 => Ok(Self::NeutralStrokeLarge),
238 0x06 => Ok(Self::TeethSurprised),
239 0x0D => Ok(Self::LipsExtraLarge),
240 0x07 => Ok(Self::LipsUp),
241 0x09 => Ok(Self::NeutralDown),
242 0x02 => Ok(Self::Surprised),
243 0x11 => Ok(Self::TeethMiddle),
244 0x03 => Ok(Self::NeutralStroke),
245 0x04 => Ok(Self::LipsExtraSmall),
246 0x0F => Ok(Self::Malicious),
247 0x0B => Ok(Self::LipsDual),
248 0x14 => Ok(Self::NeutralComma),
249 0x12 => Ok(Self::NeutralUp),
250 0x0E => Ok(Self::TeethLarge),
251 0x0C => Ok(Self::WaveAngry),
252 _ => Err(()),
253 }
254 }
255}
256
257impl From<LipsType> for u8 {
259 fn from(value: LipsType) -> Self {
260 match value {
261 LipsType::Neutral => 0x17,
262 LipsType::NeutralLips => 0x01,
263 LipsType::Smile => 0x13,
264 LipsType::SmileStroke => 0x15,
265 LipsType::SmileTeeth => 0x16,
266 LipsType::LipsSmall => 0x05,
267 LipsType::LipsLarge => 0x00,
268 LipsType::Wave => 0x08,
269 LipsType::WaveAngrySmall => 0x0A,
270 LipsType::NeutralStrokeLarge => 0x10,
271 LipsType::TeethSurprised => 0x06,
272 LipsType::LipsExtraLarge => 0x0D,
273 LipsType::LipsUp => 0x07,
274 LipsType::NeutralDown => 0x09,
275 LipsType::Surprised => 0x02,
276 LipsType::TeethMiddle => 0x11,
277 LipsType::NeutralStroke => 0x03,
278 LipsType::LipsExtraSmall => 0x04,
279 LipsType::Malicious => 0x0F,
280 LipsType::LipsDual => 0x0B,
281 LipsType::NeutralComma => 0x14,
282 LipsType::NeutralUp => 0x12,
283 LipsType::TeethLarge => 0x0E,
284 LipsType::WaveAngry => 0x0C,
285 }
286 }
287}