into_a_byte/
lib.rs

1#![no_std]
2
3/// Build ORed byte from members of tuple of Into<u8> that acts as a bit switch.
4///
5/// # Example
6///
7/// Built byte is used to send to a I2C devise for example.
8///
9/// ```
10/// use into_a_byte::*;
11///
12/// enum FunctionA {
13///     Enabled = 1 << 3,
14///     Disabled = 0,
15/// }
16///
17/// enum FunctionB {
18///     Enabled = 1 << 2,
19///     Disabled = 0,
20/// }
21///
22/// enum FunctionC {
23///     Enabled = 1 << 1,
24///     Disabled = 0,
25/// }
26///
27/// enum FunctionD {
28///     Enabled = 1,
29///     Disabled = 0,
30/// }
31///
32/// enums_into_u8!(FunctionA, FunctionB, FunctionC, FunctionD);
33///
34/// fn send_to_device(value: (FunctionA, FunctionB, FunctionC, FunctionD)) {
35///     // A byte for send to a register for example.
36///     let byte = value.into_a_byte();
37///
38///     // TODO
39/// }
40///
41/// fn main() {
42///     send_to_device((
43///         FunctionA::Enabled,
44///         FunctionB::Disabled,
45///         FunctionC::Enabled,
46///         FunctionD::Enabled,
47///     ));
48/// }
49/// ```
50pub trait IntoAByte {
51    fn into_a_byte(self) -> u8;
52}
53
54impl<A: Into<u8>> IntoAByte for (A,) {
55    fn into_a_byte(self) -> u8 {
56        let (a,) = self;
57        a.into()
58    }
59}
60
61impl<A: Into<u8>, B: Into<u8>> IntoAByte for (A, B) {
62    fn into_a_byte(self) -> u8 {
63        let (a, b) = self;
64        a.into() | b.into()
65    }
66}
67
68impl<A: Into<u8>, B: Into<u8>, C: Into<u8>> IntoAByte for (A, B, C) {
69    fn into_a_byte(self) -> u8 {
70        let (a, b, c) = self;
71        a.into() | b.into() | c.into()
72    }
73}
74
75impl<A: Into<u8>, B: Into<u8>, C: Into<u8>, D: Into<u8>> IntoAByte for (A, B, C, D) {
76    fn into_a_byte(self) -> u8 {
77        let (a, b, c, d) = self;
78        a.into() | b.into() | c.into() | d.into()
79    }
80}
81
82impl<A: Into<u8>, B: Into<u8>, C: Into<u8>, D: Into<u8>, E: Into<u8>> IntoAByte
83    for (A, B, C, D, E)
84{
85    fn into_a_byte(self) -> u8 {
86        let (a, b, c, d, e) = self;
87        a.into() | b.into() | c.into() | d.into() | e.into()
88    }
89}
90
91impl<A: Into<u8>, B: Into<u8>, C: Into<u8>, D: Into<u8>, E: Into<u8>, F: Into<u8>> IntoAByte
92    for (A, B, C, D, E, F)
93{
94    fn into_a_byte(self) -> u8 {
95        let (a, b, c, d, e, f) = self;
96        a.into() | b.into() | c.into() | d.into() | e.into() | f.into()
97    }
98}
99
100impl<A: Into<u8>, B: Into<u8>, C: Into<u8>, D: Into<u8>, E: Into<u8>, F: Into<u8>, G: Into<u8>>
101    IntoAByte for (A, B, C, D, E, F, G)
102{
103    fn into_a_byte(self) -> u8 {
104        let (a, b, c, d, e, f, g) = self;
105        a.into() | b.into() | c.into() | d.into() | e.into() | f.into() | g.into()
106    }
107}
108
109impl<
110        A: Into<u8>,
111        B: Into<u8>,
112        C: Into<u8>,
113        D: Into<u8>,
114        E: Into<u8>,
115        F: Into<u8>,
116        G: Into<u8>,
117        H: Into<u8>,
118    > IntoAByte for (A, B, C, D, E, F, G, H)
119{
120    fn into_a_byte(self) -> u8 {
121        let (a, b, c, d, e, f, g, h) = self;
122        a.into() | b.into() | c.into() | d.into() | e.into() | f.into() | g.into() | h.into()
123    }
124}
125
126/// Helper to impl Into<u8> for enums.
127///
128/// ```
129/// use into_a_byte::enums_into_u8;
130///
131/// enum FunctionA {
132///     Enabled = 1 << 3,
133///     Disabled = 0,
134/// }
135///
136/// enum FunctionB {
137///     Enabled = 1 << 2,
138///     Disabled = 0,
139/// }
140///
141/// enum FunctionC {
142///     Enabled = 1 << 1,
143///     Disabled = 0,
144/// }
145///
146/// enum FunctionD {
147///     Enabled = 1,
148///     Disabled = 0,
149/// }
150///
151/// enums_into_u8!(FunctionA, FunctionB, FunctionC, FunctionD);
152/// ```
153#[macro_export]
154macro_rules! enums_into_u8 {
155    ( $( $x:ident ),* ) => {
156        $(
157            impl Into<u8> for $x {
158                fn into(self) -> u8 {
159                    self as u8
160                }
161            }
162        )*
163
164    };
165}
166
167#[cfg(test)]
168mod tests {
169    use crate::*;
170
171    #[test]
172    fn it_works() {
173        #[allow(unused)]
174        enum FunctionA {
175            Enabled = 1 << 3,
176            Disabled = 0,
177        }
178
179        #[allow(unused)]
180        enum FunctionB {
181            Enabled = 1 << 2,
182            Disabled = 0,
183        }
184
185        #[allow(unused)]
186        enum FunctionC {
187            Enabled = 1 << 1,
188            Disabled = 0,
189        }
190
191        #[allow(unused)]
192        enum FunctionD {
193            Enabled = 1,
194            Disabled = 0,
195        }
196
197        enums_into_u8!(FunctionA, FunctionB, FunctionC, FunctionD);
198
199        fn send_to_device(value: (FunctionA, FunctionB, FunctionC, FunctionD)) {
200            assert_eq!(value.into_a_byte(), 0b0000_1011)
201        }
202
203        send_to_device((
204            FunctionA::Enabled,
205            FunctionB::Disabled,
206            FunctionC::Enabled,
207            FunctionD::Enabled,
208        ))
209    }
210}