commit
This commit is contained in:
parent
13f307d387
commit
3e129bd3d6
20 changed files with 1245 additions and 41 deletions
|
@ -7,6 +7,5 @@ edition = "2021"
|
|||
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"
|
||||
|
|
|
@ -2,7 +2,6 @@ use std::any::TypeId;
|
|||
use std::io;
|
||||
use std::io::BufRead;
|
||||
|
||||
use either::Either;
|
||||
use serde::de::DeserializeOwned;
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -24,41 +23,34 @@ pub trait DecksterHandler {
|
|||
fn handle(&mut self, event: HandlerEvent);
|
||||
}
|
||||
|
||||
enum Stage<I, H: DecksterHandler> {
|
||||
Initialization(I),
|
||||
Active(H),
|
||||
}
|
||||
|
||||
pub fn run<
|
||||
GlobalConfig: Clone + DeserializeOwned + 'static,
|
||||
KeyConfig: Clone + DeserializeOwned + 'static,
|
||||
KnobConfig: Clone + DeserializeOwned + 'static,
|
||||
H: DecksterHandler,
|
||||
I: FnOnce(InitialHandlerMessage<KeyConfig, KnobConfig>) -> Result<H, HandlerInitializationError>,
|
||||
I: FnOnce(InitialHandlerMessage<GlobalConfig, KeyConfig, KnobConfig>) -> Result<H, HandlerInitializationError>,
|
||||
>(
|
||||
init_handler: I,
|
||||
) -> Result<(), RunError> {
|
||||
let mut handler: Either<H, I> = Either::Right(init_handler);
|
||||
let mut stage: Stage<I, H> = Stage::Initialization(init_handler);
|
||||
|
||||
let requires_global_config = TypeId::of::<GlobalConfig>() != TypeId::of::<()>();
|
||||
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?;
|
||||
let line = line.map_err(RunError::LineIo)?;
|
||||
|
||||
match handler {
|
||||
Either::Left(mut h) => {
|
||||
let event: HandlerEvent = serde_json::from_str(&line).map_err(|e| RunError::LineDeserialization {
|
||||
line,
|
||||
description: e.to_string(),
|
||||
})?;
|
||||
|
||||
let should_stop = matches!(event, HandlerEvent::Stop);
|
||||
|
||||
h.handle(event);
|
||||
handler = Either::Left(h);
|
||||
|
||||
if should_stop {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Either::Right(init_handler) => {
|
||||
let initial_message = serde_json::from_str::<InitialHandlerMessage<KeyConfig, KnobConfig>>(&line);
|
||||
match stage {
|
||||
Stage::Initialization(init_handler) => {
|
||||
// TODO: Serialize the global config and each key/knob config separately for more specific error messages.
|
||||
let initial_message = serde_json::from_str::<InitialHandlerMessage<GlobalConfig, KeyConfig, KnobConfig>>(&line);
|
||||
|
||||
match initial_message {
|
||||
Ok(initial_message) => match init_handler(initial_message) {
|
||||
|
@ -67,7 +59,7 @@ pub fn run<
|
|||
"{}",
|
||||
serde_json::to_string(&HandlerInitializationResultMessage::Ready).expect("serialization of a known value always works")
|
||||
);
|
||||
handler = Either::Left(h)
|
||||
stage = Stage::Active(h)
|
||||
}
|
||||
Err(error) => {
|
||||
println!(
|
||||
|
@ -82,6 +74,7 @@ pub fn run<
|
|||
"{}",
|
||||
serde_json::to_string(&HandlerInitializationResultMessage::Error {
|
||||
error: HandlerInitializationError::InvalidConfig {
|
||||
requires_global_config,
|
||||
supports_keys,
|
||||
supports_knobs,
|
||||
message: err.to_string().into_boxed_str(),
|
||||
|
@ -93,6 +86,21 @@ pub fn run<
|
|||
}
|
||||
}
|
||||
}
|
||||
Stage::Active(mut h) => {
|
||||
let event: HandlerEvent = serde_json::from_str(&line).map_err(|e| RunError::LineDeserialization {
|
||||
line,
|
||||
description: e.to_string(),
|
||||
})?;
|
||||
|
||||
let should_stop = matches!(event, HandlerEvent::Stop);
|
||||
|
||||
h.handle(event);
|
||||
stage = Stage::Active(h);
|
||||
|
||||
if should_stop {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,8 @@ pub enum HandlerCommand {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct InitialHandlerMessage<KeyConfig: Clone, KnobConfig: Clone> {
|
||||
pub struct InitialHandlerMessage<GlobalConfig: Clone, KeyConfig: Clone, KnobConfig: Clone> {
|
||||
pub global_config: GlobalConfig,
|
||||
pub key_configs: HashMap<KeyPath, KeyConfig>,
|
||||
pub knob_configs: HashMap<KnobPath, KnobConfig>,
|
||||
}
|
||||
|
@ -106,6 +107,7 @@ pub enum HandlerInitializationResultMessage {
|
|||
pub enum HandlerInitializationError {
|
||||
#[error("The provided handler config is invalid: {message}")]
|
||||
InvalidConfig {
|
||||
requires_global_config: bool,
|
||||
supports_keys: bool,
|
||||
supports_knobs: bool,
|
||||
message: Box<str>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue