pub mod builtins;
pub mod classifier;
pub mod dispatch;
pub mod exec;
pub mod expand;
mod io;
pub mod parser;
mod pty;
mod redirect;
mod terminal;
pub mod typo;
pub use dispatch::{execute, try_builtin, try_execute_ai_pipe};
#[derive(Debug, Clone, PartialEq)]
pub enum LoopAction {
Continue,
Exit,
Restart,
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct CommandResult {
pub stdout: String,
pub stderr: String,
pub exit_code: i32,
pub action: LoopAction,
pub used_alt_screen: bool,
}
impl CommandResult {
pub fn success(stdout: String) -> Self {
Self {
stdout,
stderr: String::new(),
exit_code: 0,
action: LoopAction::Continue,
used_alt_screen: false,
}
}
pub fn error(stderr: String, exit_code: i32) -> Self {
Self {
stdout: String::new(),
stderr,
exit_code,
action: LoopAction::Continue,
used_alt_screen: false,
}
}
pub fn exit_with(exit_code: i32) -> Self {
Self {
stdout: String::new(),
stderr: String::new(),
exit_code,
action: LoopAction::Exit,
used_alt_screen: false,
}
}
pub fn restart() -> Self {
Self {
stdout: String::new(),
stderr: String::new(),
exit_code: 0,
action: LoopAction::Restart,
used_alt_screen: false,
}
}
}
#[cfg(test)]
mod loop_action_tests {
use super::*;
#[test]
fn restart_is_distinct_from_continue_and_exit() {
assert_ne!(LoopAction::Restart, LoopAction::Continue);
assert_ne!(LoopAction::Restart, LoopAction::Exit);
assert_ne!(LoopAction::Continue, LoopAction::Exit);
}
#[test]
fn command_result_restart_fields() {
let result = CommandResult::restart();
assert_eq!(result.action, LoopAction::Restart);
assert_eq!(result.exit_code, 0);
assert!(result.stdout.is_empty());
assert!(result.stderr.is_empty());
assert!(!result.used_alt_screen);
}
#[test]
fn command_result_success_is_continue() {
let result = CommandResult::success("output".to_string());
assert_eq!(result.action, LoopAction::Continue);
assert_eq!(result.exit_code, 0);
}
#[test]
fn command_result_exit_with_is_exit() {
let result = CommandResult::exit_with(42);
assert_eq!(result.action, LoopAction::Exit);
assert_eq!(result.exit_code, 42);
}
#[test]
fn command_result_error_is_continue() {
let result = CommandResult::error("err".to_string(), 1);
assert_eq!(result.action, LoopAction::Continue);
assert_eq!(result.exit_code, 1);
}
}