1bitflags! {
2 struct EntryModeFlags: u8 {
3 const ENTRY_MODE = 0b0000_0100;
4 const CURSOR_MOVE_INCREMENT = 0b0000_0010;
5 const DISPLAY_SHIFT_ON = 0b0000_0001;
6 const CURSOR_MOVE_DECREMENT = 0b0000_0000;
7 const DISPLAY_SHIFT_OFF = 0b0000_0000;
8 }
9}
10
11#[derive(Clone, Copy)]
13pub enum MoveDirection {
14 Increment,
16 Decrement,
18}
19
20impl From<MoveDirection> for EntryModeFlags {
21 fn from(direction: MoveDirection) -> Self {
22 match direction {
23 MoveDirection::Increment => EntryModeFlags::CURSOR_MOVE_INCREMENT,
24 MoveDirection::Decrement => EntryModeFlags::CURSOR_MOVE_DECREMENT,
25 }
26 }
27}
28
29#[derive(Clone, Copy)]
31pub enum DisplayShift {
32 On,
33 Off,
34}
35
36impl From<DisplayShift> for EntryModeFlags {
37 fn from(shift: DisplayShift) -> Self {
38 match shift {
39 DisplayShift::On => EntryModeFlags::DISPLAY_SHIFT_ON,
40 DisplayShift::Off => EntryModeFlags::DISPLAY_SHIFT_OFF,
41 }
42 }
43}
44
45pub struct EntryModeBuilder {
47 move_direction: MoveDirection,
48 display_shift: DisplayShift,
49}
50
51impl EntryModeBuilder {
52 pub fn set_move_direction(&mut self, direction: MoveDirection) -> &mut Self {
55 self.move_direction = direction;
56 self
57 }
58
59 pub fn set_display_shift(&mut self, shift: DisplayShift) -> &mut Self {
66 self.display_shift = shift;
67 self
68 }
69
70 pub(crate) fn build_command(&self) -> u8 {
71 let mut cmd = EntryModeFlags::ENTRY_MODE;
72
73 cmd |= EntryModeFlags::from(self.move_direction);
74 cmd |= EntryModeFlags::from(self.display_shift);
75
76 cmd.bits()
77 }
78}
79
80impl Default for EntryModeBuilder {
81 fn default() -> Self {
90 Self {
91 move_direction: MoveDirection::Increment,
92 display_shift: DisplayShift::Off,
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 const ENTRY_MODE_FLAG: u8 = 0b0000_0100;
102 const MOVE_DIRECTION_FLAG: u8 = 0b0000_0010;
103 const DISPLAY_SHIFT_FLAG: u8 = 0b0000_0001;
104
105 fn has_bit(value: u8, bitmask: u8) -> bool {
106 value & bitmask == bitmask
107 }
108
109 #[test]
110 fn entry_mode_flag() {
111 let b = EntryModeBuilder::default();
112 let cmd = b.build_command();
113
114 assert!(has_bit(cmd, ENTRY_MODE_FLAG));
115 }
116
117 #[test]
118 fn default_move_direction() {
119 let b = EntryModeBuilder::default();
120 let cmd = b.build_command();
121
122 assert!(has_bit(cmd, MOVE_DIRECTION_FLAG));
123 }
124
125 #[test]
126 fn set_move_direction() {
127 let mut b = EntryModeBuilder::default();
128
129 let cmd = b.build_command();
130 assert!(has_bit(cmd, MOVE_DIRECTION_FLAG));
131
132 b.set_move_direction(MoveDirection::Decrement);
133
134 let cmd = b.build_command();
135 assert_eq!(has_bit(cmd, MOVE_DIRECTION_FLAG), false);
136 }
137
138 #[test]
139 fn default_display_shift() {
140 let b = EntryModeBuilder::default();
141 let cmd = b.build_command();
142
143 assert_eq!(has_bit(cmd, DISPLAY_SHIFT_FLAG), false);
144 }
145
146 #[test]
147 fn set_display_shift() {
148 let mut b = EntryModeBuilder::default();
149
150 let cmd = b.build_command();
151 assert_eq!(has_bit(cmd, DISPLAY_SHIFT_FLAG), false);
152
153 b.set_display_shift(DisplayShift::On);
154
155 let cmd = b.build_command();
156 assert!(has_bit(cmd, DISPLAY_SHIFT_FLAG));
157 }
158}