1use std::time::Duration;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub enum DataBits {
10 Five,
12 Six,
14 Seven,
16 #[default]
18 Eight,
19}
20
21impl From<DataBits> for serialport::DataBits {
22 fn from(value: DataBits) -> Self {
23 match value {
24 DataBits::Five => serialport::DataBits::Five,
25 DataBits::Six => serialport::DataBits::Six,
26 DataBits::Seven => serialport::DataBits::Seven,
27 DataBits::Eight => serialport::DataBits::Eight,
28 }
29 }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
34pub enum StopBits {
35 #[default]
37 One,
38 Two,
40}
41
42impl From<StopBits> for serialport::StopBits {
43 fn from(value: StopBits) -> Self {
44 match value {
45 StopBits::One => serialport::StopBits::One,
46 StopBits::Two => serialport::StopBits::Two,
47 }
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
53pub enum Parity {
54 #[default]
56 None,
57 Odd,
59 Even,
61}
62
63impl From<Parity> for serialport::Parity {
64 fn from(value: Parity) -> Self {
65 match value {
66 Parity::None => serialport::Parity::None,
67 Parity::Odd => serialport::Parity::Odd,
68 Parity::Even => serialport::Parity::Even,
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
75pub enum FlowControl {
76 #[default]
78 None,
79 Software,
81 Hardware,
83}
84
85impl From<FlowControl> for serialport::FlowControl {
86 fn from(value: FlowControl) -> Self {
87 match value {
88 FlowControl::None => serialport::FlowControl::None,
89 FlowControl::Software => serialport::FlowControl::Software,
90 FlowControl::Hardware => serialport::FlowControl::Hardware,
91 }
92 }
93}
94
95#[derive(Debug, Clone)]
97pub struct SerialConfig {
98 pub baud_rate: u32,
100 pub data_bits: DataBits,
102 pub stop_bits: StopBits,
104 pub parity: Parity,
106 pub flow_control: FlowControl,
108 pub read_timeout: Duration,
110 pub write_timeout: Duration,
112}
113
114impl Default for SerialConfig {
115 fn default() -> Self {
116 Self {
117 baud_rate: 9600,
118 data_bits: DataBits::Eight,
119 stop_bits: StopBits::One,
120 parity: Parity::None,
121 flow_control: FlowControl::None,
122 read_timeout: Duration::from_millis(1000),
123 write_timeout: Duration::from_millis(1000),
124 }
125 }
126}
127
128impl SerialConfig {
129 pub fn new() -> Self {
131 Self::default()
132 }
133
134 pub fn builder() -> SerialConfigBuilder {
136 SerialConfigBuilder::new()
137 }
138
139 pub fn with_baud_rate(mut self, baud_rate: u32) -> Self {
141 self.baud_rate = baud_rate;
142 self
143 }
144
145 pub fn with_data_bits(mut self, data_bits: DataBits) -> Self {
147 self.data_bits = data_bits;
148 self
149 }
150
151 pub fn with_stop_bits(mut self, stop_bits: StopBits) -> Self {
153 self.stop_bits = stop_bits;
154 self
155 }
156
157 pub fn with_parity(mut self, parity: Parity) -> Self {
159 self.parity = parity;
160 self
161 }
162
163 pub fn with_flow_control(mut self, flow_control: FlowControl) -> Self {
165 self.flow_control = flow_control;
166 self
167 }
168
169 pub fn with_read_timeout_ms(mut self, ms: u64) -> Self {
171 self.read_timeout = Duration::from_millis(ms);
172 self
173 }
174
175 pub fn with_write_timeout_ms(mut self, ms: u64) -> Self {
177 self.write_timeout = Duration::from_millis(ms);
178 self
179 }
180
181 pub fn with_timeout_ms(self, ms: u64) -> Self {
183 self.with_read_timeout_ms(ms).with_write_timeout_ms(ms)
184 }
185
186 pub fn preset_115200_8n1() -> Self {
190 Self::default().with_baud_rate(115200)
191 }
192
193 pub fn preset_9600_8n1() -> Self {
195 Self::default()
196 }
197
198 pub fn preset_57600_8n1() -> Self {
200 Self::default().with_baud_rate(57600)
201 }
202
203 pub fn preset_38400_8n1() -> Self {
205 Self::default().with_baud_rate(38400)
206 }
207
208 pub fn preset_19200_8n1() -> Self {
210 Self::default().with_baud_rate(19200)
211 }
212}
213
214#[derive(Debug, Default)]
216pub struct SerialConfigBuilder {
217 config: SerialConfig,
218}
219
220impl SerialConfigBuilder {
221 pub fn new() -> Self {
223 Self::default()
224 }
225
226 pub fn baud_rate(mut self, rate: u32) -> Self {
228 self.config.baud_rate = rate;
229 self
230 }
231
232 pub fn data_bits(mut self, bits: DataBits) -> Self {
234 self.config.data_bits = bits;
235 self
236 }
237
238 pub fn stop_bits(mut self, bits: StopBits) -> Self {
240 self.config.stop_bits = bits;
241 self
242 }
243
244 pub fn parity(mut self, parity: Parity) -> Self {
246 self.config.parity = parity;
247 self
248 }
249
250 pub fn flow_control(mut self, flow: FlowControl) -> Self {
252 self.config.flow_control = flow;
253 self
254 }
255
256 pub fn read_timeout(mut self, timeout: Duration) -> Self {
258 self.config.read_timeout = timeout;
259 self
260 }
261
262 pub fn write_timeout(mut self, timeout: Duration) -> Self {
264 self.config.write_timeout = timeout;
265 self
266 }
267
268 pub fn build(self) -> SerialConfig {
270 self.config
271 }
272}
273
274#[cfg(test)]
275mod tests {
276 use super::*;
277
278 #[test]
279 fn test_default_config() {
280 let config = SerialConfig::default();
281 assert_eq!(config.baud_rate, 9600);
282 assert_eq!(config.data_bits, DataBits::Eight);
283 assert_eq!(config.stop_bits, StopBits::One);
284 assert_eq!(config.parity, Parity::None);
285 }
286
287 #[test]
288 fn test_builder() {
289 let config = SerialConfig::builder()
290 .baud_rate(115200)
291 .data_bits(DataBits::Seven)
292 .parity(Parity::Even)
293 .build();
294
295 assert_eq!(config.baud_rate, 115200);
296 assert_eq!(config.data_bits, DataBits::Seven);
297 assert_eq!(config.parity, Parity::Even);
298 }
299
300 #[test]
301 fn test_presets() {
302 let config = SerialConfig::preset_115200_8n1();
303 assert_eq!(config.baud_rate, 115200);
304
305 let config = SerialConfig::preset_9600_8n1();
306 assert_eq!(config.baud_rate, 9600);
307 }
308
309 #[test]
310 fn test_fluent_api() {
311 let config = SerialConfig::new()
312 .with_baud_rate(38400)
313 .with_timeout_ms(500);
314
315 assert_eq!(config.baud_rate, 38400);
316 assert_eq!(config.read_timeout, Duration::from_millis(500));
317 assert_eq!(config.write_timeout, Duration::from_millis(500));
318 }
319}