88 lines
3.2 KiB
Rust
88 lines
3.2 KiB
Rust
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(())
|
|
}
|