commit
This commit is contained in:
parent
1904e3e96a
commit
b5a7ab3c6b
71 changed files with 921 additions and 1297 deletions
12
crates/deckster_mode/Cargo.toml
Normal file
12
crates/deckster_mode/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "deckster_mode"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
deckster_shared = { path = "../deckster_shared" }
|
||||
thiserror = "1.0.56"
|
||||
im = "15.1.0"
|
||||
either = "1.9.0"
|
||||
serde = { version = "1.0.196", default-features = false }
|
||||
serde_json = "1.0.113"
|
88
crates/deckster_mode/src/lib.rs
Normal file
88
crates/deckster_mode/src/lib.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
use std::any::TypeId;
|
||||
use std::io;
|
||||
use std::io::BufRead;
|
||||
|
||||
use either::Either;
|
||||
use serde::de::DeserializeOwned;
|
||||
use thiserror::Error;
|
||||
|
||||
use deckster_shared::handler_communication::HandlerInitializationResultMessage;
|
||||
pub use deckster_shared::handler_communication::{HandlerEvent, HandlerInitializationError, InitialHandlerMessage};
|
||||
pub use deckster_shared::path::*;
|
||||
pub use deckster_shared::state::{KeyStyleByStateMap, KnobStyleByStateMap};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RunError {
|
||||
#[error("A stdin line could not be read.")]
|
||||
LineIo(#[from] io::Error),
|
||||
|
||||
#[error("A stdin line could not be deserialized: {description}")]
|
||||
LineDeserialization { line: String, description: String },
|
||||
}
|
||||
|
||||
pub trait DecksterHandler {
|
||||
fn handle(&mut self, event: HandlerEvent);
|
||||
}
|
||||
|
||||
pub fn run<
|
||||
KeyConfig: Clone + DeserializeOwned + 'static,
|
||||
KnobConfig: Clone + DeserializeOwned + 'static,
|
||||
H: DecksterHandler,
|
||||
I: FnOnce(InitialHandlerMessage<KeyConfig, KnobConfig>) -> Result<H, HandlerInitializationError>,
|
||||
>(
|
||||
init_handler: I,
|
||||
) -> Result<(), RunError> {
|
||||
let mut handler: Either<H, I> = Either::Right(init_handler);
|
||||
|
||||
let supports_keys = TypeId::of::<KeyConfig>() != TypeId::of::<()>();
|
||||
let supports_knobs = TypeId::of::<KnobConfig>() != TypeId::of::<()>();
|
||||
|
||||
let handle = io::stdin().lock();
|
||||
for line in handle.lines() {
|
||||
let line = line?;
|
||||
|
||||
match handler {
|
||||
Either::Left(mut h) => {
|
||||
let event: HandlerEvent = serde_json::from_str(&line).map_err(|e| RunError::LineDeserialization {
|
||||
line,
|
||||
description: e.to_string(),
|
||||
})?;
|
||||
|
||||
h.handle(event);
|
||||
handler = Either::Left(h);
|
||||
}
|
||||
Either::Right(init_handler) => {
|
||||
let initial_message = serde_json::from_str::<InitialHandlerMessage<KeyConfig, KnobConfig>>(&line);
|
||||
|
||||
match initial_message {
|
||||
Ok(initial_message) => match init_handler(initial_message) {
|
||||
Ok(h) => {
|
||||
println!("{}", serde_json::to_string(&HandlerInitializationResultMessage::Ready).unwrap());
|
||||
handler = Either::Left(h)
|
||||
}
|
||||
Err(error) => {
|
||||
println!("{}", serde_json::to_string(&HandlerInitializationResultMessage::Error { error }).unwrap());
|
||||
return Ok(());
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(&HandlerInitializationResultMessage::Error {
|
||||
error: HandlerInitializationError::InvalidConfig {
|
||||
supports_keys,
|
||||
supports_knobs,
|
||||
message: err.to_string().into_boxed_str(),
|
||||
}
|
||||
})
|
||||
.unwrap()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue