From 3b27ce15cace19804031024f286754aedf86205e Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Sat, 13 Sep 2025 22:10:20 +0800 Subject: feat: `executor`, executs `tasks` --- src/client/executor/tasks.rs | 77 +++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 19 deletions(-) (limited to 'src/client/executor/tasks.rs') diff --git a/src/client/executor/tasks.rs b/src/client/executor/tasks.rs index 90094de..c69b310 100644 --- a/src/client/executor/tasks.rs +++ b/src/client/executor/tasks.rs @@ -1,29 +1,68 @@ -use std::str::FromStr; +pub(crate) struct Task { + pub name: &'static str, + pub exec: fn(&[&str]) -> Result, +} -pub(crate) trait Task: FromStr { - type Err: std::fmt::Display; - type Success: std::fmt::Display = String; +pub(crate) const TASKS: &[Task] = &[ + Task { + name: "nop", + exec: no_op, + }, + Task { + name: "exec", + exec: exec, + }, +]; - fn execute() -> Result::Err>; +fn no_op(_: &[&str]) -> Result { + Ok("".to_string()) } -pub(crate) trait IntoTask { - type Err: std::fmt::Display; +fn exec(cmds: &[&str]) -> Result { + use std::process::Command; + // TODO: fmt and add exit code, and add support for both stdout and stderr, and support for no output + match Command::new(cmds[0]).args(&cmds[1..]).output() { + Ok(o) => { + if o.status.success() { + Ok(String::from_utf8(o.stdout) + .unwrap_or("Failed decoding vec -> String".to_string()) + .to_string()) + } else { + Err(String::from_utf8(o.stderr) + .unwrap_or("Failed decoding vec -> String".to_string()) + .to_string()) + } + } + Err(e) => Err(e.to_string()), + } +} - fn into_task(self) -> Result; +pub(crate) enum IntoTaskErr { + NotFound, +} + +pub(crate) trait IntoTask { + fn into_task<'a>(self) -> Result<&'a Task, IntoTaskErr>; } impl IntoTask for String { - type Err = ::Err; + fn into_task<'a>(self) -> Result<&'a Task, IntoTaskErr> { + for task in TASKS { + if task.name == self { + return Ok(task); + } + } + Err(IntoTaskErr::NotFound) + } +} - fn into_task(self) -> Result {} +impl IntoTask for &str { + fn into_task<'a>(self) -> Result<&'a Task, IntoTaskErr> { + for task in TASKS { + if task.name == self { + return Ok(task); + } + } + Err(IntoTaskErr::NotFound) + } } -// -// impl Task for { -// type Err = std::num::ParseIntError; -// type Success = u32; -// -// fn execute() -> Result { -// Ok(42) -// } -// } -- cgit v1.2.3