streamdeck-workspace/streamdeck-daemon/src/port.rs

67 lines
2 KiB
Rust

use crate::message::Input;
use tokio::io::{AsyncReadExt, ReadHalf, WriteHalf};
use tokio_serial::SerialStream;
pub(crate) struct ReadPort(ReadHalf<SerialStream>, String);
pub(crate) struct WritePort(WriteHalf<SerialStream>, String);
pub(crate) struct Port(SerialStream, String);
#[derive(Clone, Debug)]
pub(crate) struct DeckConfig {
pub(crate) port_name: String,
pub(crate) product_name: String,
pub(crate) serial_number: String,
}
impl ReadPort {
pub(crate) async fn read_keys(&mut self) -> std::io::Result<Input> {
let num_keys = self.0.read_u8().await?;
let mut vec = vec![0; num_keys as usize];
self.0.read_exact(&mut vec).await?;
Ok(Input::from_vec(vec))
}
}
impl Port {
pub(crate) async fn open(name: String) -> anyhow::Result<Self> {
tokio::fs::metadata(&name).await?; // check port exists
let port = streamdeck_handshake::handshake(name.clone().into()).await?;
Ok(Port(port, name))
}
pub(crate) async fn config(&mut self) -> anyhow::Result<DeckConfig> {
let port_name = self.1.clone();
let serial_number = self.serial_number().await?;
let product_name = self.product_name().await?;
Ok(DeckConfig {
port_name,
serial_number,
product_name,
})
}
pub(crate) fn split(self) -> (ReadPort, WritePort) {
let (read, write) = tokio::io::split(self.0);
(ReadPort(read, self.1.clone()), WritePort(write, self.1))
}
async fn serial_number(&mut self) -> anyhow::Result<String> {
let bytes = streamdeck_commands::identity(&mut self.0).await?;
Ok(base16ct::lower::encode_string(&bytes))
}
async fn product_name(&mut self) -> anyhow::Result<String> {
Ok(streamdeck_commands::name(&mut self.0).await?)
}
}
impl std::fmt::Debug for Port {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Port").field("name", &self.1).finish()
}
}