encdec_base/helpers/
bitflags.rs1use core::fmt::Debug;
2
3use bitflags::{Flag, Flags, Bits};
4
5use crate::{decode::DecodeOwned, encode::Encode, EncDec, Error};
6
7pub trait EncDecBitflags {}
11
12impl <T: Flags + Debug + EncDecBitflags> Encode for T where
13 <T as Flags>::Bits: Encode<Error = Error>,
14{
15 type Error = crate::Error;
16
17 fn encode_len(&self) -> Result<usize, Self::Error> {
18 Ok(size_of::<<T as Flags>::Bits>())
19 }
20
21 fn encode(&self, buff: &mut [u8]) -> Result<usize, Self::Error> {
22 if buff.len() < self.encode_len()? {
24 return Err(Error::Length);
25 }
26
27 let b = self.bits();
29
30 b.encode(buff)
32 }
33}
34
35impl <T: Flags + Debug + EncDecBitflags> DecodeOwned for T where
36 <T as Flags>::Bits: DecodeOwned<Output = <T as Flags>::Bits, Error = Error>,
37{
38 type Error = crate::Error;
39
40 type Output = T;
41
42 fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
43 if buff.len() < size_of::<<T as Flags>::Bits>() {
44 return Err(Error::Length);
45 }
46
47 let (bits, n) = <T as Flags>::Bits::decode_owned(buff)?;
48
49 let f = <T as Flags>::from_bits_retain(bits);
50
51 Ok((f, n))
52 }
53}
54
55#[cfg(test)]
56mod test {
57 use bitflags::bitflags;
58
59 use crate::helpers::test_encode_decode;
60
61 use super::*;
62
63 bitflags!{
64 #[derive(Copy, Clone, Debug, PartialEq)]
65 pub struct TestFlags: u16 {
66 const A = 0b0001;
67 const B = 0b0010;
68 }
69 }
70
71 impl EncDecBitflags for TestFlags {}
72
73 #[test]
74 fn bitflags_encode_decode() {
75 let tests = &[
76 TestFlags::A,
77 TestFlags::B,
78 TestFlags::empty(),
79 TestFlags::all(),
80 ];
81
82
83 let mut buff = [0u8; 32];
84 for t in tests {
85 test_encode_decode(&mut buff, *t);
86 }
87 }
88
89 #[test]
90 fn bitflags_encode_fails() {
91
92 let a = TestFlags::A;
93 let mut b = [0u8; 1];
94
95 a.encode(&mut b).expect_err("buffer too short");
97 TestFlags::decode_owned(&b).expect_err("buffer too short");
99 }
100}