use rhai::plugin::{
mem, Dynamic, FnAccess, FnNamespace, NativeCallContext, PluginFunction, RhaiResult, TypeId,
};
use rhai::Module;
#[derive(Debug, serde::Deserialize)]
pub struct CmdParameters {
pub command: String,
pub args: Option<Vec<String>>,
#[serde(default = "default_timeout", with = "humantime_serde")]
pub timeout: std::time::Duration,
pub user: Option<String>,
pub group: Option<String>,
}
const fn default_timeout() -> std::time::Duration {
std::time::Duration::from_secs(30)
}
#[rhai::plugin::export_module]
pub mod cmd {
use crate::api::EngineResult;
type Cmd = rhai::Shared<crate::dsl::cmd::service::Cmd>;
#[rhai_fn(return_raw)]
pub fn build(parameters: rhai::Map) -> EngineResult<Cmd> {
let parameters = rhai::serde::from_dynamic::<CmdParameters>(¶meters.into())?;
Ok(rhai::Shared::new(crate::dsl::cmd::service::Cmd {
timeout: parameters.timeout,
user: parameters.user,
group: parameters.group,
command: parameters.command,
args: parameters.args,
}))
}
#[rhai_fn(global, name = "run", return_raw, pure)]
pub fn run(cmd: &mut Cmd) -> EngineResult<rhai::Map> {
cmd.run()
.map(crate::dsl::cmd::service::Cmd::status_to_map)
.map_err::<Box<rhai::EvalAltResult>, _>(|e| e.to_string().into())
}
#[doc(hidden)]
#[rhai_fn(global, name = "run", return_raw, pure)]
pub fn run_with_args(cmd: &mut Cmd, args: rhai::Array) -> EngineResult<rhai::Map> {
let args = args
.into_iter()
.map(rhai::Dynamic::try_cast)
.collect::<Option<Vec<String>>>()
.ok_or_else::<Box<rhai::EvalAltResult>, _>(|| {
"all cmd arguments must be strings".into()
})?;
cmd.run_with_args(&args)
.map(crate::dsl::cmd::service::Cmd::status_to_map)
.map_err::<Box<rhai::EvalAltResult>, _>(|e| e.to_string().into())
}
}