mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2025-12-12 13:56:16 +00:00
feat: tauri serial polyfill
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user