1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crate::*;

// TODO: detect parameters

#[derive(Debug, Clone)]
pub(crate) struct Service {}

impl service::Service for Service {
  fn new(_config: config::Values) -> Self {
    Self {}
  }
}

#[derive(Debug, Clone)]
pub(crate) struct SerialPort {
  pub(crate) path: String,
  pub(crate) baud_rate: u32,
}

impl Service {
  #[tracing::instrument(skip(self))]
  pub(crate) async fn scan_modbus(&self) -> Vec<SerialPort> {
    let available = match serialport::available_ports() {
      Ok(available) => available,
      Err(_) => return Vec::new(),
    };

    tracing::trace!("Matching {:?}", available);
    let matched = available
      .into_iter()
      .filter(|port| {
        port.port_type == serialport::SerialPortType::Unknown
          || matches!(port.port_type, serialport::SerialPortType::UsbPort(_))
      })
      .filter(|port| FILE_PATH_REGEX.is_match(&port.port_name))
      .map(|port| SerialPort {
        path: port.port_name,
        baud_rate: 38400,
      })
      .collect::<Vec<_>>();
    tracing::trace!("Matched {:?}", matched);

    matched
  }
}

lazy_static::lazy_static! {
  static ref FILE_PATH_REGEX: regex::Regex = {
    #[allow(clippy::unwrap_used, reason = "valid static regex")]
    let regex = regex::Regex::new("^/[^/]+(/[^/]+)+$").unwrap();
    regex
  };
}