rotary_encoder/
lib.rs

1extern crate futures;
2
3use futures::{Poll, Stream};
4
5#[derive(Copy,Clone,Debug,Eq,PartialEq)]
6pub enum Direction {
7    CW,
8    CCW,
9}
10
11// A B
12// Clockwise
13// 0 0
14// 0 1
15// 1 1
16// 1 0
17//
18// Counter-clockwise
19// 1 0
20// 1 1
21// 0 1
22// 0 0
23impl Direction {
24    pub fn from(old: (u8, u8), new: (u8, u8)) -> Option<Self> {
25        use Direction::*;
26        match (old, new) {
27            ((0, 0), (0, 1)) => Some(CW),
28            ((0, 1), (1, 1)) => Some(CW),
29            ((1, 1), (1, 0)) => Some(CW),
30            ((1, 0), (0, 0)) => Some(CW),
31            ((1, 0), (1, 1)) => Some(CCW),
32            ((1, 1), (0, 1)) => Some(CCW),
33            ((0, 1), (0, 0)) => Some(CCW),
34            ((0, 0), (1, 0)) => Some(CCW),
35            _ => None,
36        }
37    }
38}
39
40#[derive(Copy,Clone,Debug,Eq,PartialEq)]
41enum Pin {
42    A,
43    B,
44}
45
46type InternalStream<S> where S: Stream<Item = u8> + 'static =
47    Box<Stream<Item = Direction, Error = S::Error> + 'static>;
48
49/// A Stream of rotation directions decoded from a rotary encoder.
50pub struct RotaryEncoder<S>(InternalStream<S>) where S: Stream<Item = u8> + 'static;
51
52impl<S> RotaryEncoder<S>
53    where S: Stream<Item = u8>
54{
55    pub fn new(a: S, b: S) -> Self {
56        let mut values = (2, 2);
57        RotaryEncoder(Box::new(a.map(|v| (Pin::A, v))
58            .select(b.map(|v| (Pin::B, v)))
59            .filter_map(move |(p, val)| {
60                let previous = values;
61                match p {
62                    Pin::A => values.0 = val,
63                    Pin::B => values.1 = val,
64                }
65                Direction::from(previous, values)
66            })))
67    }
68}
69
70impl<S> Stream for RotaryEncoder<S>
71    where S: Stream<Item = u8> + 'static
72{
73    type Item = Direction;
74    type Error = S::Error;
75
76    fn poll(&mut self) -> Poll<Option<Direction>, S::Error> {
77        self.0.poll()
78    }
79}