spectrusty_formats/tap/pulse/
encoding.rs1use core::num::NonZeroU32;
9use std::io::{Error, Read};
10use super::consts::*;
11
12#[derive(Debug)]
14pub enum PulseIterState {
15 Lead{
17 countdown: u16
19 },
20 Sync1,
22 Sync2,
24 Data{
26 current: u8,
29 pulse: u8 },
32 Done,
34 Error(Error)
36}
37
38#[derive(Debug)]
55pub struct ReadEncPulseIter<R> {
56 rd: R,
57 state: PulseIterState,
58 flag: u8,
59}
60
61impl PulseIterState {
62 pub fn err(&self) -> Option<&Error> {
64 match self {
65 PulseIterState::Error(ref error) => Some(error),
66 _ => None
67 }
68 }
69 pub fn is_done(&self) -> bool {
72 matches!(self, PulseIterState::Done|PulseIterState::Error(..))
73 }
74 pub fn is_lead(&self) -> bool {
76 matches!(self, PulseIterState::Lead {..})
77 }
78 pub fn is_data(&self) -> bool {
80 matches!(self, PulseIterState::Data {..})
81 }
82 pub fn is_sync1(&self) -> bool {
84 matches!(self, PulseIterState::Sync1)
85 }
86 pub fn is_sync2(&self) -> bool {
88 matches!(self, PulseIterState::Sync2)
89 }
90}
91
92impl<R> ReadEncPulseIter<R> {
93 pub fn state(&self) -> &PulseIterState {
95 &self.state
96 }
97 pub fn flag(&self) -> u8 {
99 self.flag
100 }
101 pub fn err(&self) -> Option<&Error> {
103 self.state.err()
104 }
105 pub fn is_done(&self) -> bool {
108 self.state.is_done()
109 }
110 pub fn get_mut(&mut self) -> &mut R {
112 &mut self.rd
113 }
114 pub fn get_ref(&self) -> &R {
116 &self.rd
117 }
118 pub fn into_inner(self) -> R {
120 self.rd
121 }
122 pub fn with_state_and_flag(mut self, state: PulseIterState, flag: u8) -> Self {
125 self.state = state;
126 self.flag = flag;
127 self
128 }
129}
130
131impl<R: Read> ReadEncPulseIter<R> {
132 pub fn new(rd: R) -> Self {
134 let mut epi = ReadEncPulseIter { rd, state: PulseIterState::Done, flag: 0 };
135 epi.reset();
136 epi
137 }
138 pub fn reset(&mut self) {
147 let (flag, state) = match self.rd.by_ref().bytes().next() {
148 Some(Ok(flag)) => (flag, PulseIterState::Lead {
149 countdown: if flag & 0x80 == 0 {
150 LEAD_PULSES_HEAD
151 } else {
152 LEAD_PULSES_DATA
153 }
154 }),
155 Some(Err(error)) => (0, PulseIterState::Error(error)),
156 None => (0, PulseIterState::Done)
157 };
158 self.flag = flag;
159 self.state = state;
160 }
161 pub fn data_from_next(&mut self) {
170 self.state = match self.rd.by_ref().bytes().next() {
171 Some(Ok(current)) => PulseIterState::Data { current, pulse: 0 },
172 Some(Err(error)) => PulseIterState::Error(error),
173 None => PulseIterState::Done
174 };
175 }
176}
177
178impl<R: Read> Iterator for ReadEncPulseIter<R> {
179 type Item = NonZeroU32;
180 fn next(&mut self) -> Option<NonZeroU32> {
181 match self.state {
182 PulseIterState::Lead {ref mut countdown} => {
183 match *countdown - 1 {
184 0 => {
185 self.state = PulseIterState::Sync1
186 }
187 res => {
188 *countdown = res
189 }
190 }
191 Some(LEAD_PULSE_LENGTH)
192 }
193 PulseIterState::Sync1 => {
194 self.state = PulseIterState::Sync2;
195 Some(SYNC_PULSE1_LENGTH)
196 }
197 PulseIterState::Sync2 => {
198 self.state = PulseIterState::Data { current: self.flag, pulse: 0 };
199 Some(SYNC_PULSE2_LENGTH)
200 }
201 PulseIterState::Data { ref mut current, ref mut pulse } => {
202 let bit_one: bool = *current & 0x80 != 0;
203 if *pulse == 15 {
204 self.state = match self.rd.by_ref().bytes().next() {
205 Some(Ok(current)) => PulseIterState::Data { current, pulse: 0 },
206 Some(Err(error)) => PulseIterState::Error(error),
207 None => PulseIterState::Done
208 };
209 }
210 else {
211 if *pulse & 1 == 1 {
212 *current = current.rotate_left(1);
213 }
214 *pulse += 1;
215 }
216 Some(if bit_one { ONE_PULSE_LENGTH } else { ZERO_PULSE_LENGTH })
217 }
218 _ => None
219 }
220 }
221}
222
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227 use std::io::Cursor;
228
229 #[test]
230 fn read_enc_pulse_iter_works() {
231 let data = [0xFF, 0xA5, 0x00];
232 let mut iter = ReadEncPulseIter::new(Cursor::new(data));
233 assert_eq!(false, iter.is_done());
234 for delta in iter.by_ref().take(LEAD_PULSES_DATA as usize) {
235 assert_eq!(LEAD_PULSE_LENGTH, delta);
236 }
237 assert_eq!(false, iter.is_done());
238 assert_eq!(Some(SYNC_PULSE1_LENGTH), iter.next());
239 assert_eq!(Some(SYNC_PULSE2_LENGTH), iter.next());
240 assert_eq!(false, iter.is_done());
241 assert_eq!(vec![
242 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
243 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
244 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
245 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
246
247 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
248 ONE_PULSE_LENGTH, ONE_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
249 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
250 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ONE_PULSE_LENGTH, ONE_PULSE_LENGTH,
251
252 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
253 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
254 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
255 ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH, ZERO_PULSE_LENGTH,
256 ], iter.by_ref().collect::<Vec<_>>());
257 assert_eq!(true, iter.is_done());
258
259 let data = [0x00];
260 let mut iter = ReadEncPulseIter::new(Cursor::new(data));
261 assert_eq!(false, iter.is_done());
262 for delta in iter.by_ref().take(LEAD_PULSES_HEAD as usize) {
263 assert_eq!(LEAD_PULSE_LENGTH, delta);
264 }
265 assert_eq!(false, iter.is_done());
266 assert_eq!(Some(SYNC_PULSE1_LENGTH), iter.next());
267 assert_eq!(Some(SYNC_PULSE2_LENGTH), iter.next());
268 assert_eq!(false, iter.is_done());
269 assert_eq!(vec![ZERO_PULSE_LENGTH; 16], iter.by_ref().collect::<Vec<_>>());
270 assert_eq!(true, iter.is_done());
271
272 let mut iter = ReadEncPulseIter::new(Cursor::new([]));
273 assert_eq!(true, iter.is_done());
274 assert_eq!(None, iter.next());
275 }
276}