// Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use std::sync:: Mutex; use std::io::ErrorKind; use std::thread; use std::time::Duration; use std::collections::HashMap; use tauri::State; #[derive(Default)] struct PortMap(Mutex>>); #[tauri::command] async fn read_serial(port_name: &str, port_map: State<'_, PortMap>) -> Result<(), String> { match port_map.0.lock().unwrap().get(port_name) { Some(port) => { let mut clone = port.try_clone().expect("Failed to clone"); let mut buffer: Vec = vec![0; 1024]; println!("Reading serial"); loop { println!("."); match clone.read(buffer.as_mut_slice()) { Ok(bytes_read) => { if bytes_read > 0 { let data = &buffer[..bytes_read]; let data = String::from_utf8_lossy(data).to_string(); if !data.trim().is_empty() { println!("{}", data.trim()); } } }, Err(ref e) if e.kind() == ErrorKind::TimedOut => (), Err(e) => return Err(e.to_string()), }; thread::sleep(std::time::Duration::from_millis(100)); } } None => { println!("Port not found"); Ok(()) } } } #[tauri::command] async fn write_serial(input: &str, port_name: &str, port_map: State<'_, PortMap>) -> Result<(), String> { println!("Trying to write"); match port_map.0.lock().unwrap().get(port_name) { Some(port) => { let mut clone = port.try_clone().expect("Failed to clone"); println!("Writing to serial"); match clone.write(input.as_bytes()) { Ok(_) => { println!("Writing to serial succes"); Ok(()) }, Err(err) => Err(err.to_string()), } } None => { println!("Writing to serial not found"); Ok(()) } } } #[tauri::command] fn get_serial_ports() -> Vec { let ports = serialport::available_ports().expect("No ports found"); let mut vec: Vec = Vec::new(); for p in ports { vec.push(p.port_name); } vec } #[tauri::command] async fn open_port(app_handle: tauri::AppHandle, port_map: State<'_, PortMap>) -> Result<(), String> { match serialport::new("/dev/ttyUSB0", 9600).timeout(Duration::from_millis(10)).open() { Ok(port) => { port_map.0.lock().unwrap().insert("/dev/ttyUSB0".to_string(), port); println!("Port open"); }, Err(err) => return Err(err.to_string()), }; Ok(()) } fn main() { tauri::Builder::default() .manage(PortMap::default()) .invoke_handler(tauri::generate_handler![get_serial_ports, read_serial, write_serial, open_port]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }