aoer_plotty_rs/plotter/
mod.rs

1use serialport;
2use std::io::Write;
3use std::io::{BufRead, BufReader, BufWriter};
4use std::ops::DerefMut;
5use std::time::Duration;
6
7pub mod error;
8pub use error::PlotterConnectionError;
9
10const DEFAULT_TIMEOUT: u64 = 30000;
11
12pub trait PlotterTransport {
13    fn write_line(&mut self, buf: &str) -> std::io::Result<()>;
14    fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize>;
15    fn flush(&mut self) -> std::io::Result<()>;
16}
17
18pub enum PlotterConnection {
19    SerialReadWrite(Box<dyn BufRead>, Box<dyn Write>),
20}
21
22impl PlotterConnection {
23    /// Given a URI in the form of serial:///dev/ttySomethingOrOther@115200,
24    /// open up a serial connection on the /dev/ttySomethingOrOther at 115200 bps.
25    pub fn from_uri(uri: &str) -> Result<PlotterConnection, PlotterConnectionError> {
26        let url = url::Url::parse(uri)?;
27        if url.scheme() == "serial" {
28            let parts: Vec<&str> = url.path().split("@").collect();
29            if parts.len() == 2 {
30                let path = parts[0].to_string();
31                let bps = parts[1].to_string().parse::<u32>()?;
32                let sp = serialport::new(path, bps)
33                    .timeout(Duration::from_millis(DEFAULT_TIMEOUT))
34                    .open()?;
35                let reader = BufReader::new(sp.try_clone()?);
36                let writer = BufWriter::new(sp);
37                Ok(PlotterConnection::SerialReadWrite(
38                    Box::new(reader),
39                    Box::new(writer),
40                ))
41            } else {
42                Err(PlotterConnectionError::UnknownError)
43            }
44        } else {
45            Err(PlotterConnectionError::UnknownError)
46        }
47    }
48}
49
50impl PlotterTransport for PlotterConnection {
51    fn write_line(&mut self, buf: &str) -> std::io::Result<()> {
52        match self {
53            PlotterConnection::SerialReadWrite(_, ref mut bwrite) => bwrite
54                .deref_mut()
55                .write_all((buf.to_owned() + "\n").as_bytes()),
56        }
57    }
58
59    fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize> {
60        match self {
61            PlotterConnection::SerialReadWrite(ref mut bread, _) => {
62                bread.deref_mut().read_line(buf)
63            }
64        }
65    }
66
67    fn flush(&mut self) -> std::io::Result<()> {
68        match self {
69            PlotterConnection::SerialReadWrite(_, ref mut bwrite) => bwrite.deref_mut().flush(),
70        }
71    }
72}
73
74#[cfg(test)]
75mod test {
76    // use super::*;
77    // use std::time::Duration;
78
79    /*
80    #[tests]
81    fn test_from_url(){
82        let mut pc=PlotterConnection::from_uri("serial:///dev/foobar@38400").expect("This sucks");
83        &pc.write_line("FAILED");
84        let flushed = &pc.flush();
85        println!("Flush result: {:?}", flushed);
86        match flushed {
87            Ok(_) => assert!(false), // We failed the tests
88            Err(err) => println!("The failure: {}", err.to_string())
89        }
90
91    }
92    */
93}