aoer_plotty_rs/plotter/
mod.rs1use 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 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 }