use crate::error::CliError;
use std::io::{self, Write};
use std::process::{Command, Stdio};
pub fn execute() -> Result<(), CliError> {
println!("đĻ Armature Interactive REPL");
println!("===============================");
println!("Type Rust code and press Enter to evaluate.");
println!("Type 'exit' or 'quit' to quit.");
println!("Type 'help' for more commands.");
println!();
if !is_evcxr_installed() {
println!("â ī¸ REPL requires evcxr_repl to be installed.");
println!();
println!("Install with:");
println!(" cargo install evcxr_repl");
println!();
println!("Or use the built-in simple REPL (limited functionality):");
println!(" armature repl --simple");
println!();
return Err(CliError::Tool("evcxr_repl not found".to_string()));
}
launch_evcxr_repl()
}
pub fn execute_simple() -> Result<(), CliError> {
println!("đĻ Armature Simple REPL");
println!("=======================");
println!("Type Rust expressions and press Enter.");
println!("Type 'exit' or 'quit' to quit.");
println!();
let mut history = Vec::new();
loop {
print!(">> ");
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let input = input.trim();
if input.is_empty() {
continue;
}
match input {
"exit" | "quit" => {
println!("Goodbye!");
break;
}
"help" => {
print_help();
continue;
}
"history" => {
print_history(&history);
continue;
}
"clear" => {
print!("\x1B[2J\x1B[1;1H");
continue;
}
_ => {
history.push(input.to_string());
println!("đ Input: {}", input);
println!("âšī¸ Note: Simple REPL has limited evaluation.");
println!(" Install evcxr_repl for full Rust REPL: cargo install evcxr_repl");
println!();
}
}
}
Ok(())
}
fn is_evcxr_installed() -> bool {
Command::new("evcxr")
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
fn launch_evcxr_repl() -> Result<(), CliError> {
println!("Starting evcxr REPL...");
println!();
let mut child = Command::new("evcxr")
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.map_err(CliError::Io)?;
let status = child.wait().map_err(CliError::Io)?;
if !status.success() {
return Err(CliError::Tool("evcxr_repl exited with error".to_string()));
}
Ok(())
}
fn print_help() {
println!("Available commands:");
println!(" help - Show this help message");
println!(" history - Show command history");
println!(" clear - Clear the screen");
println!(" exit - Exit the REPL");
println!(" quit - Exit the REPL");
println!();
}
fn print_history(history: &[String]) {
if history.is_empty() {
println!("No command history yet.");
return;
}
println!("Command history:");
for (i, cmd) in history.iter().enumerate() {
println!(" {}: {}", i + 1, cmd);
}
println!();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_evcxr_installed() {
let _ = is_evcxr_installed();
}
}