diff --git a/src/main.rs b/src/main.rs index 6e1a598..03c2be4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,6 +68,7 @@ async fn main() -> Result<()> { let request_context = mqtt::RequestContext { sections: sections.clone(), section_runner: section_runner.clone(), + program_runner: program_runner.clone(), }; let mut mqtt_interface = mqtt::MqttInterfaceTask::start(mqtt_options, request_context); diff --git a/src/mqtt/request/mod.rs b/src/mqtt/request/mod.rs index ae367db..e90b08b 100644 --- a/src/mqtt/request/mod.rs +++ b/src/mqtt/request/mod.rs @@ -1,4 +1,4 @@ -use crate::{model::Sections, section_runner::SectionRunner}; +use crate::{model::Sections, program_runner::ProgramRunner, section_runner::SectionRunner}; use futures_util::ready; use futures_util::FutureExt; @@ -6,11 +6,13 @@ use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; use std::{fmt, future::Future, pin::Pin, task::Poll}; +mod programs; mod sections; pub struct RequestContext { pub sections: Sections, pub section_runner: SectionRunner, + pub program_runner: ProgramRunner, } type BoxFuture = Pin>>; @@ -30,6 +32,7 @@ pub enum ErrorCode { // NotUnique = 110, NoSuchSection = 120, NoSuchSectionRun = 121, + NoSuchProgram = 122, Internal = 200, NotImplemented = 201, Timeout = 300, @@ -258,6 +261,7 @@ pub enum Request { CancelSection(sections::CancelSectionRequest), CancelSectionRunId(sections::CancelSectionRunIdRequest), PauseSectionRunner(sections::PauseSectionRunnerRequest), + RunProgram(programs::RunProgramRequest), } impl IRequest for Request { @@ -269,6 +273,7 @@ impl IRequest for Request { Request::CancelSection(req) => req.exec_erased(ctx), Request::CancelSectionRunId(req) => req.exec_erased(ctx), Request::PauseSectionRunner(req) => req.exec_erased(ctx), + Request::RunProgram(req) => req.exec_erased(ctx), } } } diff --git a/src/mqtt/request/programs.rs b/src/mqtt/request/programs.rs new file mode 100644 index 0000000..b105990 --- /dev/null +++ b/src/mqtt/request/programs.rs @@ -0,0 +1,32 @@ +use super::*; +use crate::{model::ProgramId, program_runner::ProgramRunnerError}; +use eyre::WrapErr; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RunProgramRequest { + program_id: ProgramId, +} + +impl IRequest for RunProgramRequest { + type Response = ResponseMessage; + + fn exec(&mut self, ctx: &mut RequestContext) -> RequestFuture { + let mut program_runner = ctx.program_runner.clone(); + let program_id = self.program_id; + Box::pin(async move { + match program_runner.run_program_id(program_id).await { + Ok(program) => Ok(ResponseMessage::new(format!( + "running program '{}'", + program.name + ))), + Err(e @ ProgramRunnerError::InvalidProgramId(_)) => Err(RequestError::with_name( + ErrorCode::NoSuchProgram, + e, + "program", + )), + Err(e) => Err(e).wrap_err("could not run program")?, + } + }) + } +}