- Add PostgreSQL client functionality for database interactions. - Add Redis client functionality for cache and data store operations. - Extend Rhai scripting with PostgreSQL and Redis client modules. - Add documentation and test cases for both clients.
213 lines
6.7 KiB
Rust
213 lines
6.7 KiB
Rust
//! Rhai wrappers for Process module functions
|
|
//!
|
|
//! This module provides Rhai wrappers for the functions in the Process module.
|
|
|
|
use crate::process::{self, CommandResult, ProcessError, ProcessInfo, RunError};
|
|
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
|
|
use std::clone::Clone;
|
|
|
|
/// Register Process module functions with the Rhai engine
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `engine` - The Rhai engine to register the functions with
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
|
|
pub fn register_process_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register types
|
|
// register_process_types(engine)?; // Removed
|
|
|
|
// Register CommandResult type and its methods
|
|
engine.register_type_with_name::<CommandResult>("CommandResult");
|
|
engine.register_get("stdout", |r: &mut CommandResult| r.stdout.clone());
|
|
engine.register_get("stderr", |r: &mut CommandResult| r.stderr.clone());
|
|
engine.register_get("success", |r: &mut CommandResult| r.success);
|
|
engine.register_get("code", |r: &mut CommandResult| r.code);
|
|
|
|
// Register ProcessInfo type and its methods
|
|
engine.register_type_with_name::<ProcessInfo>("ProcessInfo");
|
|
engine.register_get("pid", |p: &mut ProcessInfo| p.pid);
|
|
engine.register_get("name", |p: &mut ProcessInfo| p.name.clone());
|
|
engine.register_get("memory", |p: &mut ProcessInfo| p.memory);
|
|
engine.register_get("cpu", |p: &mut ProcessInfo| p.cpu);
|
|
|
|
// Register CommandBuilder type and its methods
|
|
engine.register_type_with_name::<RhaiCommandBuilder>("CommandBuilder");
|
|
engine.register_fn("run", RhaiCommandBuilder::new_rhai); // This is the builder entry point
|
|
engine.register_fn("silent", RhaiCommandBuilder::silent); // Method on CommandBuilder
|
|
engine.register_fn("ignore_error", RhaiCommandBuilder::ignore_error); // Method on CommandBuilder
|
|
engine.register_fn("log", RhaiCommandBuilder::log); // Method on CommandBuilder
|
|
engine.register_fn("execute", RhaiCommandBuilder::execute_command); // Method on CommandBuilder
|
|
|
|
// Register other process management functions
|
|
engine.register_fn("which", which);
|
|
engine.register_fn("kill", kill);
|
|
engine.register_fn("process_list", process_list);
|
|
engine.register_fn("process_get", process_get);
|
|
|
|
// Register legacy functions for backward compatibility
|
|
engine.register_fn("run_command", run_command);
|
|
engine.register_fn("run_silent", run_silent);
|
|
engine.register_fn("run", run_with_options);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Helper functions for error conversion
|
|
fn run_error_to_rhai_error<T>(result: Result<T, RunError>) -> Result<T, Box<EvalAltResult>> {
|
|
result.map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Run error: {}", e).into(),
|
|
rhai::Position::NONE,
|
|
))
|
|
})
|
|
}
|
|
|
|
// Define a Rhai-facing builder struct
|
|
#[derive(Clone)]
|
|
struct RhaiCommandBuilder {
|
|
command: String,
|
|
die_on_error: bool,
|
|
is_silent: bool,
|
|
enable_log: bool,
|
|
}
|
|
|
|
impl RhaiCommandBuilder {
|
|
// Constructor function for Rhai (registered as `run`)
|
|
pub fn new_rhai(command: &str) -> Self {
|
|
Self {
|
|
command: command.to_string(),
|
|
die_on_error: true, // Default: die on error
|
|
is_silent: false,
|
|
enable_log: false,
|
|
}
|
|
}
|
|
|
|
// Rhai method: .silent()
|
|
pub fn silent(mut self) -> Self {
|
|
self.is_silent = true;
|
|
self
|
|
}
|
|
|
|
// Rhai method: .ignore_error()
|
|
pub fn ignore_error(mut self) -> Self {
|
|
self.die_on_error = false;
|
|
self
|
|
}
|
|
|
|
// Rhai method: .log()
|
|
pub fn log(mut self) -> Self {
|
|
self.enable_log = true;
|
|
self
|
|
}
|
|
|
|
// Rhai method: .execute() - Execute the command
|
|
pub fn execute_command(self) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
let builder = process::run(&self.command)
|
|
.die(self.die_on_error)
|
|
.silent(self.is_silent)
|
|
.log(self.enable_log);
|
|
|
|
// Execute the command
|
|
run_error_to_rhai_error(builder.execute())
|
|
}
|
|
}
|
|
|
|
fn process_error_to_rhai_error<T>(
|
|
result: Result<T, ProcessError>,
|
|
) -> Result<T, Box<EvalAltResult>> {
|
|
result.map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Process error: {}", e).into(),
|
|
rhai::Position::NONE,
|
|
))
|
|
})
|
|
}
|
|
|
|
//
|
|
// Process Management Function Wrappers
|
|
//
|
|
|
|
/// Wrapper for process::which
|
|
///
|
|
/// Check if a command exists in PATH.
|
|
pub fn which(cmd: &str) -> Dynamic {
|
|
match process::which(cmd) {
|
|
Some(path) => path.into(),
|
|
None => Dynamic::UNIT,
|
|
}
|
|
}
|
|
|
|
/// Wrapper for process::kill
|
|
///
|
|
/// Kill processes matching a pattern.
|
|
pub fn kill(pattern: &str) -> Result<String, Box<EvalAltResult>> {
|
|
process_error_to_rhai_error(process::kill(pattern))
|
|
}
|
|
|
|
/// Wrapper for process::process_list
|
|
///
|
|
/// List processes matching a pattern (or all if pattern is empty).
|
|
pub fn process_list(pattern: &str) -> Result<Array, Box<EvalAltResult>> {
|
|
let processes = process_error_to_rhai_error(process::process_list(pattern))?;
|
|
|
|
// Convert Vec<ProcessInfo> to Rhai Array
|
|
let mut array = Array::new();
|
|
for process in processes {
|
|
array.push(Dynamic::from(process));
|
|
}
|
|
|
|
Ok(array)
|
|
}
|
|
|
|
/// Wrapper for process::process_get
|
|
///
|
|
/// Get a single process matching the pattern (error if 0 or more than 1 match).
|
|
pub fn process_get(pattern: &str) -> Result<ProcessInfo, Box<EvalAltResult>> {
|
|
process_error_to_rhai_error(process::process_get(pattern))
|
|
}
|
|
|
|
/// Legacy wrapper for process::run
|
|
///
|
|
/// Run a command and return the result.
|
|
pub fn run_command(cmd: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
run_error_to_rhai_error(process::run(cmd).execute())
|
|
}
|
|
|
|
/// Legacy wrapper for process::run with silent option
|
|
///
|
|
/// Run a command silently and return the result.
|
|
pub fn run_silent(cmd: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
run_error_to_rhai_error(process::run(cmd).silent(true).execute())
|
|
}
|
|
|
|
/// Legacy wrapper for process::run with options
|
|
///
|
|
/// Run a command with options and return the result.
|
|
pub fn run_with_options(cmd: &str, options: Map) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
let mut builder = process::run(cmd);
|
|
|
|
// Apply options
|
|
if let Some(silent) = options.get("silent") {
|
|
if let Ok(silent_bool) = silent.as_bool() {
|
|
builder = builder.silent(silent_bool);
|
|
}
|
|
}
|
|
|
|
if let Some(die) = options.get("die") {
|
|
if let Ok(die_bool) = die.as_bool() {
|
|
builder = builder.die(die_bool);
|
|
}
|
|
}
|
|
|
|
if let Some(log) = options.get("log") {
|
|
if let Ok(log_bool) = log.as_bool() {
|
|
builder = builder.log(log_bool);
|
|
}
|
|
}
|
|
|
|
run_error_to_rhai_error(builder.execute())
|
|
}
|