1use core::{convert::TryFrom, ops::Not};
2
3use crate::ModbusSerializationError;
4
5#[repr(u8)]
9#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
10pub enum BitState {
11 Off = 0,
12 On = 1,
13}
14
15impl BitState {
16 pub fn is_on(self) -> bool {
17 self.into()
18 }
19}
20
21impl Default for BitState {
22 fn default() -> BitState {
23 BitState::Off
24 }
25}
26
27impl TryFrom<u16> for BitState {
28 type Error = ModbusSerializationError;
29 fn try_from(value: u16) -> Result<Self, Self::Error> {
30 match value {
31 0 => Ok(Self::Off),
32 0xFF00 => Ok(Self::On),
33 _ => Err(ModbusSerializationError::InvalidValue)
34 }
35 }
36}
37
38impl Into<u16> for BitState {
39 fn into(self) -> u16 {
40 match self {
41 Self::Off => 0,
42 Self::On => 0xFF00,
43 }
44 }
45}
46
47impl From<bool> for BitState {
48 fn from(b: bool) -> Self {
49 if b {
50 Self::On
51 } else {
52 Self::Off
53 }
54 }
55}
56
57impl Into<bool> for BitState {
58 fn into(self) -> bool {
59 match self {
60 Self::Off => false,
61 Self::On => true,
62 }
63 }
64}
65
66impl Not for BitState {
67 type Output = Self;
68
69 fn not(self) -> Self::Output {
70 match self {
71 BitState::On => BitState::Off,
72 BitState::Off => BitState::On,
73 }
74 }
75}
76
77#[cfg(test)]
78mod bitstate_test {
79 use core::convert::TryFrom;
80
81 use crate::{BitState, ModbusSerializationError};
82
83 #[test]
84 fn from_bool_true() {
85 let state_on = BitState::from(true);
86 assert_eq!(state_on, BitState::On);
87 assert_eq!(!state_on, BitState::Off);
88 assert_eq!(true, state_on.into());
89 assert_eq!(0xFF00u16, state_on.into());
90 }
91
92
93 #[test]
94 fn from_bool_false() {
95 let state_on = BitState::from(false);
96 assert_eq!(state_on, BitState::Off);
97 assert_eq!(!state_on, BitState::On);
98 assert_eq!(false, state_on.into());
99 assert_eq!(0u16, state_on.into());
100 }
101
102 #[test]
103 fn from_u16_on() {
104 let state_on = BitState::try_from(0xFF00).unwrap();
105 assert_eq!(state_on, BitState::On);
106 assert_eq!(!state_on, BitState::Off);
107 assert_eq!(true, state_on.into());
108 assert_eq!(0xFF00u16, state_on.into());
109 }
110
111 #[test]
112 fn from_u16_off() {
113 let state_on = BitState::try_from(0).unwrap();
114 assert_eq!(state_on, BitState::Off);
115 assert_eq!(!state_on, BitState::On);
116 assert_eq!(false, state_on.into());
117 assert_eq!(0u16, state_on.into());
118 }
119
120 #[test]
121 fn from_u16_invalid0() {
122 let invalid = BitState::try_from(0xF0FF).unwrap_err();
123 assert_eq!(invalid, ModbusSerializationError::InvalidValue);
124 }
125
126 #[test]
127 fn from_u16_invalid1() {
128 let invalid = BitState::try_from(0xFFFF).unwrap_err();
129 assert_eq!(invalid, ModbusSerializationError::InvalidValue);
130 }
131
132 #[test]
133 fn from_u16_invalid2() {
134 let invalid = BitState::try_from(1).unwrap_err();
135 assert_eq!(invalid, ModbusSerializationError::InvalidValue);
136 }
137}