1use crate::{Error, binary::Rgb};
2use de::{DeserializeSeed, SeqAccess, Visitor};
3use serde::de;
4
5#[derive(Debug)]
6pub(crate) struct ColorSequence {
7 data: Rgb,
8 idx: usize,
9}
10
11impl ColorSequence {
12 pub(crate) fn new(data: Rgb) -> Self {
13 ColorSequence { data, idx: 0 }
14 }
15
16 fn val(&self) -> u32 {
17 match self.idx {
18 0 => self.data.r,
19 1 => self.data.g,
20 2 => self.data.b,
21 3 => self.data.a.unwrap(),
22 _ => unreachable!(),
23 }
24 }
25}
26
27impl<'de> de::Deserializer<'de> for &'_ mut ColorSequence {
28 type Error = Error;
29
30 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
31 where
32 V: Visitor<'de>,
33 {
34 visitor.visit_u32(self.val())
35 }
36
37 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
38 where
39 V: Visitor<'de>,
40 {
41 visitor.visit_seq(self)
42 }
43
44 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
45 where
46 V: Visitor<'de>,
47 {
48 visitor.visit_seq(self)
49 }
50
51 fn deserialize_tuple_struct<V>(
52 self,
53 _name: &'static str,
54 _len: usize,
55 visitor: V,
56 ) -> Result<V::Value, Self::Error>
57 where
58 V: Visitor<'de>,
59 {
60 visitor.visit_seq(self)
61 }
62
63 serde::forward_to_deserialize_any! {
64 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
65 bytes byte_buf option unit unit_struct newtype_struct map struct enum identifier ignored_any
66 }
67}
68
69impl<'de> de::Deserializer<'de> for ColorSequence {
70 type Error = Error;
71
72 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
73 where
74 V: Visitor<'de>,
75 {
76 visitor.visit_u32(self.val())
77 }
78
79 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
80 where
81 V: Visitor<'de>,
82 {
83 visitor.visit_seq(self)
84 }
85
86 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
87 where
88 V: Visitor<'de>,
89 {
90 visitor.visit_seq(self)
91 }
92
93 fn deserialize_tuple_struct<V>(
94 self,
95 _name: &'static str,
96 _len: usize,
97 visitor: V,
98 ) -> Result<V::Value, Self::Error>
99 where
100 V: Visitor<'de>,
101 {
102 visitor.visit_seq(self)
103 }
104
105 serde::forward_to_deserialize_any! {
106 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
107 bytes byte_buf option unit unit_struct newtype_struct map struct enum identifier ignored_any
108 }
109}
110
111impl<'de> SeqAccess<'de> for ColorSequence {
112 type Error = Error;
113
114 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
115 where
116 T: DeserializeSeed<'de>,
117 {
118 if (self.idx >= 3 && self.data.a.is_none()) || (self.idx >= 4 && self.data.a.is_some()) {
119 Ok(None)
120 } else {
121 let result = seed.deserialize(&mut *self);
122 self.idx += 1;
123 result.map(Some)
124 }
125 }
126
127 fn size_hint(&self) -> Option<usize> {
128 let remaining = if self.data.a.is_none() {
129 3 - self.idx
130 } else {
131 4 - self.idx
132 };
133 Some(remaining)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use crate::binary::Rgb;
141 use serde::Deserialize;
142
143 #[test]
144 fn test_color_sequence_rgb_deserialization() {
145 let rgb = Rgb {
146 r: 255,
147 g: 128,
148 b: 64,
149 a: None,
150 };
151 let seq = ColorSequence::new(rgb);
152
153 #[derive(Debug, PartialEq, Deserialize)]
154 struct RgbTuple(u32, u32, u32);
155
156 let result: RgbTuple = RgbTuple::deserialize(seq).unwrap();
157 assert_eq!(result, RgbTuple(255, 128, 64));
158 }
159
160 #[test]
161 fn test_color_sequence_rgba_deserialization() {
162 let rgb = Rgb {
163 r: 255,
164 g: 128,
165 b: 64,
166 a: Some(192),
167 };
168 let seq = ColorSequence::new(rgb);
169
170 #[derive(Debug, PartialEq, Deserialize)]
171 struct RgbaTuple(u32, u32, u32, u32);
172
173 let result: RgbaTuple = RgbaTuple::deserialize(seq).unwrap();
174 assert_eq!(result, RgbaTuple(255, 128, 64, 192));
175 }
176
177 #[test]
178 fn test_color_sequence_sequential_values() {
179 let rgb = Rgb {
180 r: 10,
181 g: 20,
182 b: 30,
183 a: Some(40),
184 };
185 let mut seq = ColorSequence::new(rgb);
186
187 use std::marker::PhantomData;
188
189 let result1 = seq.next_element_seed(PhantomData::<u32>).unwrap().unwrap();
190 assert_eq!(result1, 10);
191
192 let result2 = seq.next_element_seed(PhantomData::<u32>).unwrap().unwrap();
193 assert_eq!(result2, 20);
194
195 let result3 = seq.next_element_seed(PhantomData::<u32>).unwrap().unwrap();
196 assert_eq!(result3, 30);
197
198 let result4 = seq.next_element_seed(PhantomData::<u32>).unwrap().unwrap();
199 assert_eq!(result4, 40);
200 }
201
202 #[test]
203 fn test_color_sequence_size_hint_rgb() {
204 let rgb = Rgb {
205 r: 255,
206 g: 128,
207 b: 64,
208 a: None,
209 };
210 let seq = ColorSequence::new(rgb);
211
212 assert_eq!(seq.size_hint(), Some(3));
213 }
214
215 #[test]
216 fn test_color_sequence_size_hint_rgba() {
217 let rgb = Rgb {
218 r: 255,
219 g: 128,
220 b: 64,
221 a: Some(192),
222 };
223 let seq = ColorSequence::new(rgb);
224
225 assert_eq!(seq.size_hint(), Some(4));
226 }
227
228 #[test]
229 fn test_color_sequence_size_hint_with_progress() {
230 let rgb = Rgb {
231 r: 255,
232 g: 128,
233 b: 64,
234 a: None,
235 };
236 let mut seq = ColorSequence::new(rgb);
237
238 use std::marker::PhantomData;
239
240 seq.next_element_seed(PhantomData::<u32>).unwrap();
241 seq.next_element_seed(PhantomData::<u32>).unwrap();
242
243 assert_eq!(seq.size_hint(), Some(1));
244 }
245
246 #[test]
247 fn test_color_sequence_deserialize_any() {
248 let rgb = Rgb {
249 r: 100,
250 g: 200,
251 b: 50,
252 a: None,
253 };
254 let mut seq = ColorSequence::new(rgb);
255
256 let value: u32 = u32::deserialize(&mut seq).unwrap();
257 assert_eq!(value, 100);
258 }
259}