1use std::convert::Infallible;
2
3use crate::byte_handler::{ByteHandlerError, FromByteHandler};
4
5#[derive(Clone, Copy)]
8pub struct Glasses {
9 y: u8,
11 size: u8,
13 glasses_type: GlassesType,
15 glasses_color: GlassesColor,
17}
18
19impl Glasses {
20 pub fn new(
34 y: u8,
35 size: u8,
36 glasses_type: GlassesType,
37 glasses_color: GlassesColor,
38 ) -> Result<Self, GlassesError> {
39 if size > 7 {
40 return Err(GlassesError::SizeInvalid);
41 }
42 if y > 20 {
43 return Err(GlassesError::YInvalid);
44 }
45
46 Ok(Self {
47 y,
48 size,
49 glasses_type,
50 glasses_color,
51 })
52 }
53
54 pub fn y(&self) -> u8 {
56 self.y
57 }
58
59 pub fn size(&self) -> u8 {
61 self.size
62 }
63
64 pub fn glasses_type(&self) -> GlassesType {
66 self.glasses_type
67 }
68
69 pub fn glasses_color(&self) -> GlassesColor {
71 self.glasses_color
72 }
73
74 pub fn set_y(&mut self, y: u8) -> Result<(), GlassesError> {
80 if y > 20 {
81 return Err(GlassesError::YInvalid);
82 }
83 self.y = y;
84 Ok(())
85 }
86
87 pub fn set_size(&mut self, size: u8) -> Result<(), GlassesError> {
93 if size > 7 {
94 return Err(GlassesError::SizeInvalid);
95 }
96 self.size = size;
97 Ok(())
98 }
99
100 pub fn set_glasses_type(&mut self, glasses_type: GlassesType) {
102 self.glasses_type = glasses_type;
103 }
104
105 pub fn set_glasses_color(&mut self, glasses_color: GlassesColor) {
107 self.glasses_color = glasses_color;
108 }
109}
110
111impl FromByteHandler for Glasses {
116 type Err = GlassesError;
117 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
118 where
119 T: TryInto<crate::byte_handler::ByteHandler>,
120 Self::Err: From<T::Error>,
121 {
122 let mut handler = handler.try_into()?;
123
124 let glasses_type = GlassesType::try_from(handler.copy_byte(0) >> 4)
125 .map_err(|_| GlassesError::TypeInvalid)?;
126 let y = handler.copy_byte(1) & 0x1F;
127 handler.shift_right(1);
128 let glasses_color = GlassesColor::try_from(handler.copy_byte(0) & 0x03)
129 .map_err(|_| GlassesError::ColorInvalid)?;
130 let size = handler.copy_byte(1) >> 4;
131
132 Self::new(y, size, glasses_type, glasses_color)
133 }
134}
135
136#[derive(thiserror::Error, Debug)]
138pub enum GlassesError {
139 #[error("Type is invalid")]
141 TypeInvalid,
142 #[error("Color is invalid")]
144 ColorInvalid,
145 #[error("Size is invalid")]
147 SizeInvalid,
148 #[error("Y position is invalid")]
150 YInvalid,
151 #[error("ByteHandler Error: {0}")]
153 ByteHandlerError(#[from] ByteHandlerError),
154 #[error("")]
156 Infallible(#[from] Infallible),
157}
158
159#[derive(Clone, Copy, PartialEq, Debug)]
161pub enum GlassesColor {
162 Black,
163 Brown,
164 Red,
165 Blue,
166 Yellow,
167 Gray,
168}
169
170impl TryFrom<u8> for GlassesColor {
174 type Error = ();
175 fn try_from(value: u8) -> Result<Self, Self::Error> {
176 match value {
177 0 => Ok(Self::Black),
178 1 => Ok(Self::Brown),
179 2 => Ok(Self::Red),
180 3 => Ok(Self::Blue),
181 4 => Ok(Self::Yellow),
182 5 => Ok(Self::Gray),
183 _ => Err(()),
184 }
185 }
186}
187
188impl From<GlassesColor> for u8 {
190 fn from(value: GlassesColor) -> Self {
191 match value {
192 GlassesColor::Black => 0,
193 GlassesColor::Brown => 1,
194 GlassesColor::Red => 2,
195 GlassesColor::Blue => 3,
196 GlassesColor::Yellow => 4,
197 GlassesColor::Gray => 5,
198 }
199 }
200}
201
202#[derive(Clone, Copy, PartialEq, Debug)]
204pub enum GlassesType {
205 None,
207 Square,
208 Rectangle,
209 Rounded,
210 Oval,
211 CatEye,
212 SemiOpaqueAviator,
213 SemiOpaqueRectangle,
214 SemiOpaqueCatEye,
215}
216
217impl TryFrom<u8> for GlassesType {
221 type Error = ();
222 fn try_from(value: u8) -> Result<Self, Self::Error> {
223 match value {
224 0 => Ok(Self::None),
225 1 => Ok(Self::Square),
226 2 => Ok(Self::Rectangle),
227 3 => Ok(Self::Rounded),
228 4 => Ok(Self::Oval),
229 5 => Ok(Self::CatEye),
230 6 => Ok(Self::SemiOpaqueAviator),
231 7 => Ok(Self::SemiOpaqueRectangle),
232 8 => Ok(Self::SemiOpaqueCatEye),
233 _ => Err(()),
234 }
235 }
236}
237
238impl From<GlassesType> for u8 {
240 fn from(value: GlassesType) -> Self {
241 match value {
242 GlassesType::None => 0,
243 GlassesType::Square => 1,
244 GlassesType::Rectangle => 2,
245 GlassesType::Rounded => 3,
246 GlassesType::Oval => 4,
247 GlassesType::CatEye => 5,
248 GlassesType::SemiOpaqueAviator => 6,
249 GlassesType::SemiOpaqueRectangle => 7,
250 GlassesType::SemiOpaqueCatEye => 8,
251 }
252 }
253}