serial_core/lib.rs
1use std::error::Error as StdError;
2use std::fmt;
3use std::io;
4use std::time::Duration;
5
6pub use BaudRate::*;
7pub use CharSize::*;
8pub use Parity::*;
9pub use StopBits::*;
10pub use FlowControl::*;
11
12/// A module that exports traits that are useful to have in scope.
13///
14/// It is intended to be glob imported:
15///
16/// ```no_run
17/// use serial_core::prelude::*;
18/// ```
19pub mod prelude {
20 pub use {SerialPort, SerialPortSettings};
21}
22
23/// A type for results generated by interacting with serial ports.
24///
25/// The `Err` type is hard-wired to [`serial_core::Error`](struct.Error.html).
26pub type Result<T> = std::result::Result<T, Error>;
27
28/// Categories of errors that can occur when interacting with serial ports.
29///
30/// This list is intended to grow over time and it is not recommended to exhaustively match against
31/// it.
32#[derive(Debug,Clone,Copy,PartialEq,Eq)]
33pub enum ErrorKind {
34 /// The device is not available.
35 ///
36 /// This could indicate that the device is in use by another process or was disconnected while
37 /// performing I/O.
38 NoDevice,
39
40 /// A parameter was incorrect.
41 InvalidInput,
42
43 /// An I/O error occured.
44 ///
45 /// The type of I/O error is determined by the inner `io::ErrorKind`.
46 Io(io::ErrorKind),
47}
48
49/// An error type for serial port operations.
50#[derive(Debug)]
51pub struct Error {
52 kind: ErrorKind,
53 description: String,
54}
55
56impl Error {
57 pub fn new<T: Into<String>>(kind: ErrorKind, description: T) -> Self {
58 Error {
59 kind: kind,
60 description: description.into(),
61 }
62 }
63
64 /// Returns the corresponding `ErrorKind` for this error.
65 pub fn kind(&self) -> ErrorKind {
66 self.kind
67 }
68}
69
70impl fmt::Display for Error {
71 fn fmt(&self, fmt: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
72 fmt.write_str(&self.description)
73 }
74}
75
76impl StdError for Error {
77 fn description(&self) -> &str {
78 &self.description
79 }
80}
81
82impl From<io::Error> for Error {
83 fn from(io_error: io::Error) -> Error {
84 Error::new(ErrorKind::Io(io_error.kind()), format!("{}", io_error))
85 }
86}
87
88impl From<Error> for io::Error {
89 fn from(error: Error) -> io::Error {
90 let kind = match error.kind {
91 ErrorKind::NoDevice => io::ErrorKind::NotFound,
92 ErrorKind::InvalidInput => io::ErrorKind::InvalidInput,
93 ErrorKind::Io(kind) => kind,
94 };
95
96 io::Error::new(kind, error.description)
97 }
98}
99
100/// Serial port baud rates.
101///
102/// ## Portability
103///
104/// The `BaudRate` variants with numeric suffixes, e.g., `Baud9600`, indicate standard baud rates
105/// that are widely-supported on many systems. While non-standard baud rates can be set with
106/// `BaudOther`, their behavior is system-dependent. Some systems may not support arbitrary baud
107/// rates. Using the standard baud rates is more likely to result in portable applications.
108#[derive(Debug,Copy,Clone,PartialEq,Eq)]
109pub enum BaudRate {
110 /// 110 baud.
111 Baud110,
112
113 /// 300 baud.
114 Baud300,
115
116 /// 600 baud.
117 Baud600,
118
119 /// 1200 baud.
120 Baud1200,
121
122 /// 2400 baud.
123 Baud2400,
124
125 /// 4800 baud.
126 Baud4800,
127
128 /// 9600 baud.
129 Baud9600,
130
131 /// 19,200 baud.
132 Baud19200,
133
134 /// 38,400 baud.
135 Baud38400,
136
137 /// 57,600 baud.
138 Baud57600,
139
140 /// 115,200 baud.
141 Baud115200,
142
143 /// Non-standard baud rates.
144 ///
145 /// `BaudOther` can be used to set non-standard baud rates by setting its member to be the
146 /// desired baud rate.
147 ///
148 /// ```no_run
149 /// serial_core::BaudOther(4_000_000); // 4,000,000 baud
150 /// ```
151 ///
152 /// Non-standard baud rates may not be supported on all systems.
153 BaudOther(usize),
154}
155
156impl BaudRate {
157 /// Creates a `BaudRate` for a particular speed.
158 ///
159 /// This function can be used to select a `BaudRate` variant from an integer containing the
160 /// desired baud rate.
161 ///
162 /// ## Example
163 ///
164 /// ```
165 /// # use serial_core::BaudRate;
166 /// assert_eq!(BaudRate::Baud9600, BaudRate::from_speed(9600));
167 /// assert_eq!(BaudRate::Baud115200, BaudRate::from_speed(115200));
168 /// assert_eq!(BaudRate::BaudOther(4000000), BaudRate::from_speed(4000000));
169 /// ```
170 pub fn from_speed(speed: usize) -> BaudRate {
171 match speed {
172 110 => BaudRate::Baud110,
173 300 => BaudRate::Baud300,
174 600 => BaudRate::Baud600,
175 1200 => BaudRate::Baud1200,
176 2400 => BaudRate::Baud2400,
177 4800 => BaudRate::Baud4800,
178 9600 => BaudRate::Baud9600,
179 19200 => BaudRate::Baud19200,
180 38400 => BaudRate::Baud38400,
181 57600 => BaudRate::Baud57600,
182 115200 => BaudRate::Baud115200,
183 n => BaudRate::BaudOther(n),
184 }
185 }
186
187 /// Returns the baud rate as an integer.
188 ///
189 /// ## Example
190 ///
191 /// ```
192 /// # use serial_core::BaudRate;
193 /// assert_eq!(9600, BaudRate::Baud9600.speed());
194 /// assert_eq!(115200, BaudRate::Baud115200.speed());
195 /// assert_eq!(4000000, BaudRate::BaudOther(4000000).speed());
196 /// ```
197 pub fn speed(&self) -> usize {
198 match *self {
199 BaudRate::Baud110 => 110,
200 BaudRate::Baud300 => 300,
201 BaudRate::Baud600 => 600,
202 BaudRate::Baud1200 => 1200,
203 BaudRate::Baud2400 => 2400,
204 BaudRate::Baud4800 => 4800,
205 BaudRate::Baud9600 => 9600,
206 BaudRate::Baud19200 => 19200,
207 BaudRate::Baud38400 => 38400,
208 BaudRate::Baud57600 => 57600,
209 BaudRate::Baud115200 => 115200,
210 BaudRate::BaudOther(n) => n,
211 }
212 }
213}
214
215/// Number of bits per character.
216#[derive(Debug,Copy,Clone,PartialEq,Eq)]
217pub enum CharSize {
218 /// 5 bits per character.
219 Bits5,
220
221 /// 6 bits per character.
222 Bits6,
223
224 /// 7 bits per character.
225 Bits7,
226
227 /// 8 bits per character.
228 Bits8,
229}
230
231/// Parity checking modes.
232///
233/// When parity checking is enabled (`ParityOdd` or `ParityEven`) an extra bit is transmitted with
234/// each character. The value of the parity bit is arranged so that the number of 1 bits in the
235/// character (including the parity bit) is an even number (`ParityEven`) or an odd number
236/// (`ParityOdd`).
237///
238/// Parity checking is disabled by setting `ParityNone`, in which case parity bits are not
239/// transmitted.
240#[derive(Debug,Copy,Clone,PartialEq,Eq)]
241pub enum Parity {
242 /// No parity bit.
243 ParityNone,
244
245 /// Parity bit sets odd number of 1 bits.
246 ParityOdd,
247
248 /// Parity bit sets even number of 1 bits.
249 ParityEven,
250}
251
252/// Number of stop bits.
253///
254/// Stop bits are transmitted after every character.
255#[derive(Debug,Copy,Clone,PartialEq,Eq)]
256pub enum StopBits {
257 /// One stop bit.
258 Stop1,
259
260 /// Two stop bits.
261 Stop2,
262}
263
264/// Flow control modes.
265#[derive(Debug,Copy,Clone,PartialEq,Eq)]
266pub enum FlowControl {
267 /// No flow control.
268 FlowNone,
269
270 /// Flow control using XON/XOFF bytes.
271 FlowSoftware,
272
273 /// Flow control using RTS/CTS signals.
274 FlowHardware,
275}
276
277/// A trait for implementing serial devices.
278///
279/// This trait is meant to be used to implement new serial port devices. To use a serial port
280/// device, the [`SerialPort`](trait.SerialPort.html) trait should be used instead. Any type that
281/// implements the `SerialDevice` trait will automatically implement the `SerialPort` trait as
282/// well.
283///
284/// To implement a new serial port device, it's necessary to define a type that can manipulate the
285/// serial port device's settings (baud rate, parity mode, etc). This type is defined by the
286/// `Settings` associated type. The current settings should be determined by reading from the
287/// hardware or operating system for every call to `read_settings()`. The settings can then be
288/// manipulated in memory before being commited to the device with `write_settings()`.
289///
290/// Types that implement `SerialDevice` must also implement `std::io::Read` and `std::io::Write`.
291/// The `read()` and `write()` operations of these traits should honor the timeout that has been
292/// set with the most recent successful call to `set_timeout()`. This timeout value should also be
293/// accessible by calling the `timeout()` method.
294///
295/// A serial port device should also provide access to some basic control signals: RTS, DTR, CTS,
296/// DSR, RI, and CD. The values for the control signals are represented as boolean values, with
297/// `true` indicating the the control signal is active.
298///
299/// Lastly, types that implement `SerialDevice` should release any acquired resources when dropped.
300pub trait SerialDevice: io::Read + io::Write {
301 /// A type that implements the settings for the serial port device.
302 ///
303 /// The `Settings` type is used to retrieve and modify the serial port's settings. This type
304 /// should own any native structures used to manipulate the device's settings, but it should
305 /// not cause any changes in the underlying hardware until written to the device with
306 /// `write_settings()`.
307 type Settings: SerialPortSettings;
308
309 /// Returns the device's current settings.
310 ///
311 /// This function attempts to read the current settings from the hardware. The hardware's
312 /// current settings may not match the settings that were most recently written to the hardware
313 /// with `write_settings()`.
314 ///
315 /// ## Errors
316 ///
317 /// This function returns an error if the settings could not be read from the underlying
318 /// hardware:
319 ///
320 /// * `NoDevice` if the device was disconnected.
321 /// * `Io` for any other type of I/O error.
322 fn read_settings(&self) -> ::Result<Self::Settings>;
323
324 /// Applies new settings to the serial device.
325 ///
326 /// This function attempts to apply all settings to the serial device. Some settings may not be
327 /// supported by the underlying hardware, in which case the result is dependent on the
328 /// implementation. A successful return value does not guarantee that all settings were
329 /// appliied successfully. To check which settings were applied by a successful write,
330 /// applications should use the `read_settings()` method to obtain the latest configuration
331 /// state from the device.
332 ///
333 /// ## Errors
334 ///
335 /// This function returns an error if the settings could not be applied to the underlying
336 /// hardware:
337 ///
338 /// * `NoDevice` if the device was disconnected.
339 /// * `InvalidInput` if a setting is not compatible with the underlying hardware.
340 /// * `Io` for any other type of I/O error.
341 fn write_settings(&mut self, settings: &Self::Settings) -> ::Result<()>;
342
343 /// Returns the current timeout.
344 fn timeout(&self) -> Duration;
345
346 /// Sets the timeout for future I/O operations.
347 fn set_timeout(&mut self, timeout: Duration) -> ::Result<()>;
348
349 /// Sets the state of the RTS (Request To Send) control signal.
350 ///
351 /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal.
352 ///
353 /// ## Errors
354 ///
355 /// This function returns an error if the RTS control signal could not be set to the desired
356 /// state on the underlying hardware:
357 ///
358 /// * `NoDevice` if the device was disconnected.
359 /// * `Io` for any other type of I/O error.
360 fn set_rts(&mut self, level: bool) -> ::Result<()>;
361
362 /// Sets the state of the DTR (Data Terminal Ready) control signal.
363 ///
364 /// Setting a value of `true` asserts the DTR control signal. `false` clears the signal.
365 ///
366 /// ## Errors
367 ///
368 /// This function returns an error if the DTR control signal could not be set to the desired
369 /// state on the underlying hardware:
370 ///
371 /// * `NoDevice` if the device was disconnected.
372 /// * `Io` for any other type of I/O error.
373 fn set_dtr(&mut self, level: bool) -> ::Result<()>;
374
375 /// Reads the state of the CTS (Clear To Send) control signal.
376 ///
377 /// This function returns a boolean that indicates whether the CTS control signal is asserted.
378 ///
379 /// ## Errors
380 ///
381 /// This function returns an error if the state of the CTS control signal could not be read
382 /// from the underlying hardware:
383 ///
384 /// * `NoDevice` if the device was disconnected.
385 /// * `Io` for any other type of I/O error.
386 fn read_cts(&mut self) -> ::Result<bool>;
387
388 /// Reads the state of the DSR (Data Set Ready) control signal.
389 ///
390 /// This function returns a boolean that indicates whether the DSR control signal is asserted.
391 ///
392 /// ## Errors
393 ///
394 /// This function returns an error if the state of the DSR control signal could not be read
395 /// from the underlying hardware:
396 ///
397 /// * `NoDevice` if the device was disconnected.
398 /// * `Io` for any other type of I/O error.
399 fn read_dsr(&mut self) -> ::Result<bool>;
400
401 /// Reads the state of the RI (Ring Indicator) control signal.
402 ///
403 /// This function returns a boolean that indicates whether the RI control signal is asserted.
404 ///
405 /// ## Errors
406 ///
407 /// This function returns an error if the state of the RI control signal could not be read from
408 /// the underlying hardware:
409 ///
410 /// * `NoDevice` if the device was disconnected.
411 /// * `Io` for any other type of I/O error.
412 fn read_ri(&mut self) -> ::Result<bool>;
413
414 /// Reads the state of the CD (Carrier Detect) control signal.
415 ///
416 /// This function returns a boolean that indicates whether the CD control signal is asserted.
417 ///
418 /// ## Errors
419 ///
420 /// This function returns an error if the state of the CD control signal could not be read from
421 /// the underlying hardware:
422 ///
423 /// * `NoDevice` if the device was disconnected.
424 /// * `Io` for any other type of I/O error.
425 fn read_cd(&mut self) -> ::Result<bool>;
426}
427
428/// A trait for serial port devices.
429///
430/// Serial port input and output is implemented through the `std::io::Read` and `std::io::Write`
431/// traits. A timeout can be set with the `set_timeout()` method and applies to all subsequent I/O
432/// operations.
433///
434/// The `SerialPort` trait exposes several common control signals. Each control signal is
435/// represented as a boolean, where `true` indicates that the signal is asserted.
436///
437/// The serial port will be closed when the value is dropped.
438pub trait SerialPort: io::Read + io::Write {
439 /// Returns the current timeout.
440 fn timeout(&self) -> Duration;
441
442 /// Sets the timeout for future I/O operations.
443 fn set_timeout(&mut self, timeout: Duration) -> ::Result<()>;
444
445 /// Configures a serial port device.
446 ///
447 /// ## Errors
448 ///
449 /// This function returns an error if the settings could not be applied to the underlying
450 /// hardware:
451 ///
452 /// * `NoDevice` if the device was disconnected.
453 /// * `InvalidInput` if a setting is not compatible with the underlying hardware.
454 /// * `Io` for any other type of I/O error.
455 fn configure(&mut self, settings: &PortSettings) -> ::Result<()>;
456
457 /// Alter the serial port's configuration.
458 ///
459 /// This method expects a function, which takes a mutable reference to the serial port's
460 /// configuration settings. The serial port's current settings, read from the device, are
461 /// yielded to the provided function. After the function returns, any changes made to the
462 /// settings object will be written back to the device.
463 ///
464 /// ## Errors
465 ///
466 /// This function returns an error if the `setup` function returns an error or if there was an
467 /// error while reading or writing the device's configuration settings:
468 ///
469 /// * `NoDevice` if the device was disconnected.
470 /// * `InvalidInput` if a setting is not compatible with the underlying hardware.
471 /// * `Io` for any other type of I/O error.
472 /// * Any error returned by the `setup` function.
473 ///
474 /// ## Example
475 ///
476 /// The following is a function that toggles a serial port's settings between one and two stop
477 /// bits:
478 ///
479 /// ```no_run
480 /// use std::io;
481 /// use serial_core::prelude::*;
482 ///
483 /// fn toggle_stop_bits<T: SerialPort>(port: &mut T) -> serial_core::Result<()> {
484 /// port.reconfigure(&|settings| {
485 /// let stop_bits = match settings.stop_bits() {
486 /// Some(serial_core::Stop1) => serial_core::Stop2,
487 /// Some(serial_core::Stop2) | None => serial_core::Stop1,
488 /// };
489 ///
490 /// settings.set_stop_bits(stop_bits);
491 /// Ok(())
492 /// })
493 /// }
494 /// ```
495 fn reconfigure(&mut self, setup: &Fn(&mut SerialPortSettings) -> ::Result<()>) -> ::Result<()>;
496
497 /// Sets the state of the RTS (Request To Send) control signal.
498 ///
499 /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal.
500 ///
501 /// ## Errors
502 ///
503 /// This function returns an error if the RTS control signal could not be set to the desired
504 /// state on the underlying hardware:
505 ///
506 /// * `NoDevice` if the device was disconnected.
507 /// * `Io` for any other type of I/O error.
508 fn set_rts(&mut self, level: bool) -> ::Result<()>;
509
510 /// Sets the state of the DTR (Data Terminal Ready) control signal.
511 ///
512 /// Setting a value of `true` asserts the DTR control signal. `false` clears the signal.
513 ///
514 /// ## Errors
515 ///
516 /// This function returns an error if the DTR control signal could not be set to the desired
517 /// state on the underlying hardware:
518 ///
519 /// * `NoDevice` if the device was disconnected.
520 /// * `Io` for any other type of I/O error.
521 fn set_dtr(&mut self, level: bool) -> ::Result<()>;
522
523 /// Reads the state of the CTS (Clear To Send) control signal.
524 ///
525 /// This function returns a boolean that indicates whether the CTS control signal is asserted.
526 ///
527 /// ## Errors
528 ///
529 /// This function returns an error if the state of the CTS control signal could not be read
530 /// from the underlying hardware:
531 ///
532 /// * `NoDevice` if the device was disconnected.
533 /// * `Io` for any other type of I/O error.
534 fn read_cts(&mut self) -> ::Result<bool>;
535
536 /// Reads the state of the DSR (Data Set Ready) control signal.
537 ///
538 /// This function returns a boolean that indicates whether the DSR control signal is asserted.
539 ///
540 /// ## Errors
541 ///
542 /// This function returns an error if the state of the DSR control signal could not be read
543 /// from the underlying hardware:
544 ///
545 /// * `NoDevice` if the device was disconnected.
546 /// * `Io` for any other type of I/O error.
547 fn read_dsr(&mut self) -> ::Result<bool>;
548
549 /// Reads the state of the RI (Ring Indicator) control signal.
550 ///
551 /// This function returns a boolean that indicates whether the RI control signal is asserted.
552 ///
553 /// ## Errors
554 ///
555 /// This function returns an error if the state of the RI control signal could not be read from
556 /// the underlying hardware:
557 ///
558 /// * `NoDevice` if the device was disconnected.
559 /// * `Io` for any other type of I/O error.
560 fn read_ri(&mut self) -> ::Result<bool>;
561
562 /// Reads the state of the CD (Carrier Detect) control signal.
563 ///
564 /// This function returns a boolean that indicates whether the CD control signal is asserted.
565 ///
566 /// ## Errors
567 ///
568 /// This function returns an error if the state of the CD control signal could not be read from
569 /// the underlying hardware:
570 ///
571 /// * `NoDevice` if the device was disconnected.
572 /// * `Io` for any other type of I/O error.
573 fn read_cd(&mut self) -> ::Result<bool>;
574}
575
576impl<T> SerialPort for T
577 where T: SerialDevice
578{
579 fn timeout(&self) -> Duration {
580 T::timeout(self)
581 }
582
583 fn set_timeout(&mut self, timeout: Duration) -> ::Result<()> {
584 T::set_timeout(self, timeout)
585 }
586
587 fn configure(&mut self, settings: &PortSettings) -> ::Result<()> {
588 let mut device_settings = try!(T::read_settings(self));
589
590 try!(device_settings.set_baud_rate(settings.baud_rate));
591 device_settings.set_char_size(settings.char_size);
592 device_settings.set_parity(settings.parity);
593 device_settings.set_stop_bits(settings.stop_bits);
594 device_settings.set_flow_control(settings.flow_control);
595
596 T::write_settings(self, &device_settings)
597 }
598
599 fn reconfigure(&mut self, setup: &Fn(&mut SerialPortSettings) -> ::Result<()>) -> ::Result<()> {
600 let mut device_settings = try!(T::read_settings(self));
601 try!(setup(&mut device_settings));
602 T::write_settings(self, &device_settings)
603 }
604
605 fn set_rts(&mut self, level: bool) -> ::Result<()> {
606 T::set_rts(self, level)
607 }
608
609 fn set_dtr(&mut self, level: bool) -> ::Result<()> {
610 T::set_dtr(self, level)
611 }
612
613 fn read_cts(&mut self) -> ::Result<bool> {
614 T::read_cts(self)
615 }
616
617 fn read_dsr(&mut self) -> ::Result<bool> {
618 T::read_dsr(self)
619 }
620
621 fn read_ri(&mut self) -> ::Result<bool> {
622 T::read_ri(self)
623 }
624
625 fn read_cd(&mut self) -> ::Result<bool> {
626 T::read_cd(self)
627 }
628}
629
630/// A trait for objects that implement serial port configurations.
631pub trait SerialPortSettings {
632 /// Returns the current baud rate.
633 ///
634 /// This function returns `None` if the baud rate could not be determined. This may occur if
635 /// the hardware is in an uninitialized state. Setting a baud rate with `set_baud_rate()`
636 /// should initialize the baud rate to a supported value.
637 fn baud_rate(&self) -> Option<BaudRate>;
638
639 /// Returns the character size.
640 ///
641 /// This function returns `None` if the character size could not be determined. This may occur
642 /// if the hardware is in an uninitialized state or is using a non-standard character size.
643 /// Setting a baud rate with `set_char_size()` should initialize the character size to a
644 /// supported value.
645 fn char_size(&self) -> Option<CharSize>;
646
647 /// Returns the parity-checking mode.
648 ///
649 /// This function returns `None` if the parity mode could not be determined. This may occur if
650 /// the hardware is in an uninitialized state or is using a non-standard parity mode. Setting
651 /// a parity mode with `set_parity()` should initialize the parity mode to a supported value.
652 fn parity(&self) -> Option<Parity>;
653
654 /// Returns the number of stop bits.
655 ///
656 /// This function returns `None` if the number of stop bits could not be determined. This may
657 /// occur if the hardware is in an uninitialized state or is using an unsupported stop bit
658 /// configuration. Setting the number of stop bits with `set_stop-bits()` should initialize the
659 /// stop bits to a supported value.
660 fn stop_bits(&self) -> Option<StopBits>;
661
662 /// Returns the flow control mode.
663 ///
664 /// This function returns `None` if the flow control mode could not be determined. This may
665 /// occur if the hardware is in an uninitialized state or is using an unsupported flow control
666 /// mode. Setting a flow control mode with `set_flow_control()` should initialize the flow
667 /// control mode to a supported value.
668 fn flow_control(&self) -> Option<FlowControl>;
669
670 /// Sets the baud rate.
671 ///
672 /// ## Errors
673 ///
674 /// If the implementation does not support the requested baud rate, this function may return an
675 /// `InvalidInput` error. Even if the baud rate is accepted by `set_baud_rate()`, it may not be
676 /// supported by the underlying hardware.
677 fn set_baud_rate(&mut self, baud_rate: BaudRate) -> ::Result<()>;
678
679 /// Sets the character size.
680 fn set_char_size(&mut self, char_size: CharSize);
681
682 /// Sets the parity-checking mode.
683 fn set_parity(&mut self, parity: Parity);
684
685 /// Sets the number of stop bits.
686 fn set_stop_bits(&mut self, stop_bits: StopBits);
687
688 /// Sets the flow control mode.
689 fn set_flow_control(&mut self, flow_control: FlowControl);
690}
691
692/// A device-indepenent implementation of serial port settings.
693#[derive(Debug,Copy,Clone,PartialEq,Eq)]
694pub struct PortSettings {
695 /// Baud rate.
696 pub baud_rate: BaudRate,
697
698 /// Character size.
699 pub char_size: CharSize,
700
701 /// Parity checking mode.
702 pub parity: Parity,
703
704 /// Number of stop bits.
705 pub stop_bits: StopBits,
706
707 /// Flow control mode.
708 pub flow_control: FlowControl,
709}
710
711impl SerialPortSettings for PortSettings {
712 fn baud_rate(&self) -> Option<BaudRate> {
713 Some(self.baud_rate)
714 }
715
716 fn char_size(&self) -> Option<CharSize> {
717 Some(self.char_size)
718 }
719
720 fn parity(&self) -> Option<Parity> {
721 Some(self.parity)
722 }
723
724 fn stop_bits(&self) -> Option<StopBits> {
725 Some(self.stop_bits)
726 }
727
728 fn flow_control(&self) -> Option<FlowControl> {
729 Some(self.flow_control)
730 }
731
732 fn set_baud_rate(&mut self, baud_rate: BaudRate) -> ::Result<()> {
733 self.baud_rate = baud_rate;
734 Ok(())
735 }
736
737 fn set_char_size(&mut self, char_size: CharSize) {
738 self.char_size = char_size;
739 }
740
741 fn set_parity(&mut self, parity: Parity) {
742 self.parity = parity;
743 }
744
745 fn set_stop_bits(&mut self, stop_bits: StopBits) {
746 self.stop_bits = stop_bits;
747 }
748
749 fn set_flow_control(&mut self, flow_control: FlowControl) {
750 self.flow_control = flow_control;
751 }
752}
753
754#[cfg(test)]
755mod tests {
756 use super::*;
757
758 fn default_port_settings() -> PortSettings {
759 PortSettings {
760 baud_rate: BaudRate::Baud9600,
761 char_size: CharSize::Bits8,
762 parity: Parity::ParityNone,
763 stop_bits: StopBits::Stop1,
764 flow_control: FlowControl::FlowNone,
765 }
766 }
767
768 #[test]
769 fn port_settings_manipulates_baud_rate() {
770 let mut settings: PortSettings = default_port_settings();
771 settings.set_baud_rate(Baud115200).unwrap();
772 assert_eq!(settings.baud_rate(), Some(Baud115200));
773 }
774
775 #[test]
776 fn port_settings_manipulates_char_size() {
777 let mut settings: PortSettings = default_port_settings();
778 settings.set_char_size(Bits7);
779 assert_eq!(settings.char_size(), Some(Bits7));
780 }
781
782 #[test]
783 fn port_settings_manipulates_parity() {
784 let mut settings: PortSettings = default_port_settings();
785 settings.set_parity(ParityEven);
786 assert_eq!(settings.parity(), Some(ParityEven));
787 }
788
789 #[test]
790 fn port_settings_manipulates_stop_bits() {
791 let mut settings: PortSettings = default_port_settings();
792 settings.set_stop_bits(Stop2);
793 assert_eq!(settings.stop_bits(), Some(Stop2));
794 }
795
796 #[test]
797 fn port_settings_manipulates_flow_control() {
798 let mut settings: PortSettings = default_port_settings();
799 settings.set_flow_control(FlowSoftware);
800 assert_eq!(settings.flow_control(), Some(FlowSoftware));
801 }
802}