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}