commit e9910a4b6e7e5ffac345a462affc78c01f9d11d4 Author: Aode (lion) Date: Sat Oct 2 14:46:34 2021 -0500 Implement supported commands diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..92c3348 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "streamdeck-commands" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +thiserror = "1.0.29" +tokio = { version = "1.12.0", default-features = false, features = ["io-util"] } +tokio-serial = "5.4.1" +tracing-error = "0.1.2" + +[dev-dependencies] +tokio = { version = "1.12.0", features = ["rt", "macros"] } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..37ae4d9 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,80 @@ +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use tokio_serial::SerialStream; +use tracing_error::SpanTrace; + +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, + context: SpanTrace, +} + +#[derive(Debug, thiserror::Error)] +pub enum ErrorKind { + #[error(transparent)] + Serial(#[from] tokio_serial::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), +} + +pub async fn identity(port: &mut SerialStream) -> Result, Error> { + get_prop(port, b"ident").await +} + +pub async fn author(port: &mut SerialStream) -> Result, Error> { + get_prop(port, b"author").await +} + +pub async fn repo(port: &mut SerialStream) -> Result, Error> { + get_prop(port, b"repo").await +} + +pub async fn reset(port: &mut SerialStream) -> Result<(), Error> { + send_command(port, b"reset").await +} + +async fn send_command(port: &mut Port, command: &[u8]) -> Result<(), Error> +where + Port: AsyncWrite + Unpin, +{ + port.write_all(command).await?; + port.flush().await?; + + Ok(()) +} + +async fn get_prop(port: &mut Port, prop: &[u8]) -> Result, Error> +where + Port: AsyncRead + AsyncWrite + Unpin, +{ + send_command::(port, prop).await?; + + let mut len_buf = [0u8; 1]; + + port.read_exact(&mut len_buf).await?; + let input_len = len_buf[0]; + + let mut input = vec![0u8; input_len as usize]; + port.read_exact(&mut input).await?; + + Ok(input) +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "{}", self.kind)?; + std::fmt::Display::fmt(&self.context, f) + } +} + +impl From for Error +where + ErrorKind: From, +{ + fn from(error: T) -> Self { + Error { + kind: error.into(), + context: SpanTrace::capture(), + } + } +}