ws2812_flexio/
pixelstream.rs

1use crate::pixel::Pixel;
2
3pub trait PixelStreamRef {
4    fn next(&mut self) -> Option<u8>;
5}
6
7pub struct PixelStream<P, I>
8where
9    P: Pixel,
10    I: Iterator<Item = P>,
11{
12    pixel_stream: I,
13    bytes_iter: Option<P::BytesIter>,
14    finished: bool,
15}
16
17impl<I, P> PixelStream<P, I>
18where
19    P: Pixel,
20    I: Iterator<Item = P>,
21{
22    fn new(pixel_stream: I) -> Self {
23        Self {
24            pixel_stream,
25            bytes_iter: None,
26            finished: false,
27        }
28    }
29}
30
31impl<I, P> PixelStreamRef for PixelStream<P, I>
32where
33    P: Pixel,
34    I: Iterator<Item = P>,
35{
36    fn next(&mut self) -> Option<u8> {
37        loop {
38            if self.finished {
39                return None;
40            }
41
42            if self.bytes_iter.is_none() {
43                self.bytes_iter = self.pixel_stream.next().map(|p| p.into_ws2812_bytes());
44            }
45
46            if let Some(bytes_iter) = self.bytes_iter.as_mut() {
47                if let Some(byte) = bytes_iter.next() {
48                    return Some(byte);
49                } else {
50                    self.bytes_iter = None;
51                }
52            } else {
53                self.finished = true;
54            }
55        }
56    }
57}
58
59/// Converts an iterator of pixels into a pixel stream, usable by the driver's `write` function.
60pub trait IntoPixelStream {
61    /// The pixel type.
62    type Pixel: Pixel;
63    /// The pixel iterator type.
64    type PixelIter: Iterator<Item = Self::Pixel>;
65
66    /// Converts the current object into a pixel stream.
67    fn into_pixel_stream(self) -> PixelStream<Self::Pixel, Self::PixelIter>;
68}
69
70impl<T> IntoPixelStream for T
71where
72    T: IntoIterator,
73    <T as IntoIterator>::Item: Pixel,
74{
75    type Pixel = <T as IntoIterator>::Item;
76    type PixelIter = <T as IntoIterator>::IntoIter;
77
78    fn into_pixel_stream(self) -> PixelStream<Self::Pixel, Self::PixelIter> {
79        PixelStream::new(self.into_iter())
80    }
81}