feat: tauri serial polyfill

This commit is contained in:
2023-08-04 00:08:28 +02:00
parent 9c1918e683
commit 42922e7ce0
23 changed files with 660 additions and 486 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "app"
version = "0.3.0"
version = "0.4.0"
description = "A Tauri App"
authors = ["Thea Schöbl <dev@theaninova.de>"]
license = "AGPL-3"

View File

@@ -1,39 +1,99 @@
use serde::Serialize;
use serialport::{available_ports, SerialPortType};
use serialport::{available_ports, SerialPort, SerialPortType};
use std::collections::HashMap;
use std::io::{Read, Write};
use std::sync::{Arc, Mutex};
use tauri::plugin::{Builder, TauriPlugin};
use tauri::{command, generate_handler, Runtime};
use tauri::{command, generate_handler, Manager, Runtime, State};
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("serial")
.invoke_handler(generate_handler![get_serial_ports])
.invoke_handler(generate_handler![
get_serial_ports,
open,
close,
read,
write
])
.setup(move |app_handle| {
app_handle.manage(SerialState::default());
Ok(())
})
.build()
}
#[derive(Default)]
pub struct SerialState {
handles: Arc<Mutex<HashMap<String, Box<dyn SerialPort>>>>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct WebSerialPortInfo {
pub name: String,
pub product_id: u16,
pub vendor_id: u16,
pub usb_product_id: u16,
pub usb_vendor_id: u16,
pub serial_number: Option<String>,
pub manufacturer: Option<String>,
pub product: Option<String>,
}
#[command]
fn get_serial_ports() -> Vec<WebSerialPortInfo> {
available_ports()
.unwrap()
fn get_serial_ports() -> Result<Vec<WebSerialPortInfo>, String> {
Ok(available_ports()
.map_err(|err| err.to_string())?
.iter()
.filter_map(|port| match &port.port_type {
SerialPortType::UsbPort(usb) => Some(WebSerialPortInfo {
name: port.port_name.clone(),
vendor_id: usb.vid,
product_id: usb.pid,
usb_vendor_id: usb.vid,
usb_product_id: usb.pid,
serial_number: usb.serial_number.clone(),
manufacturer: usb.manufacturer.clone(),
product: usb.product.clone(),
}),
_ => None,
})
.collect()
.collect())
}
#[command]
fn open(state: State<'_, SerialState>, path: String, baud_rate: u32) -> Result<(), String> {
let mut handles = state.handles.lock().map_err(|err| err.to_string())?;
if handles.contains_key(&path) {
return Ok(());
}
let port = serialport::new(path.clone(), baud_rate)
.open()
.map_err(|err| err.to_string())?;
handles.insert(path, port);
Ok(())
}
#[command]
fn close(state: State<'_, SerialState>, path: String) -> Result<(), String> {
let mut handles = state.handles.lock().map_err(|err| err.to_string())?;
handles.remove(&path).ok_or("Port is already closed")?;
Ok(())
}
#[command]
fn read(state: State<'_, SerialState>, path: String) -> Result<Vec<u8>, String> {
let mut handles = state.handles.lock().map_err(|err| err.to_string())?;
let port = handles.get_mut(&path).ok_or("Read: Port is not open")?;
let size = port.bytes_to_read().map_err(|err| err.to_string())?;
let mut buffer: Vec<u8> = vec![0; size as usize];
port.read_exact(buffer.as_mut_slice())
.map_err(|err| err.to_string())?;
Ok(buffer)
}
#[command]
fn write(state: State<'_, SerialState>, path: String, chunk: Vec<u8>) -> Result<(), String> {
let mut handles = state.handles.lock().map_err(|err| err.to_string())?;
let port = handles.get_mut(&path).ok_or("Write: Port is not open")?;
port.write_all(&chunk).map_err(|err| err.to_string())
}

View File

@@ -8,7 +8,7 @@
},
"package": {
"productName": "amacc1ng",
"version": "0.1.0"
"version": "0.4.0"
},
"tauri": {
"allowlist": {
@@ -51,7 +51,12 @@
"csp": null
},
"updater": {
"active": false
"active": true,
"endpoints": [
"http://v2202207178592194230.supersrv.de:9216/update?current_version={{current_version}}&target={{target}}&arch={{arch}}"
],
"dialog": true,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDU5QjEwMEY5RjNBRjM4MEIKUldRTE9LL3orUUN4V2FMWDZkc2l2VUdOL3FSdUMwTk1ualNac095RVZXVEpqUEtORkFsWGZaTmsK"
},
"windows": [
{