From 9e41cdfb69532c51be5a241c975cec023b8d858b Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 30 Jul 2025 20:22:36 +0200 Subject: Implement EXIT. --- src/main.rs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 408a69b..61f6663 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,14 +40,14 @@ fn main() -> Result<()> { let Ok(CommandReceivers { stdout, stderr, - exit_status, + status, }) = command.run() else { eprintln!("unimplemented command: {}", line); continue; }; - // print stdout, stderr interleaved until exit_status produces something + // print stdout, stderr interleaved until status produces something let stdout_writer = spawn(move || { loop { let Ok(bytes) = stdout.recv() else { @@ -75,9 +75,14 @@ fn main() -> Result<()> { stdout_writer.join().expect("stdout writer thread failed"); stderr_writer.join().expect("stderr writer thread failed"); - let _exit_status = exit_status + let command_result = status .recv() .expect("failed to receive exit status from command"); + + match command_result { + CommandStatus::ExitShell => break, + CommandStatus::Code(_) => {} + } } Ok(()) @@ -176,16 +181,22 @@ enum Command { Empty, } +#[derive(Debug)] +enum CommandStatus { + Code(u16), + ExitShell, +} + struct CommandReceivers { stdout: Receiver>, stderr: Receiver>, - exit_status: Receiver, + status: Receiver, } struct CommandSenders { stdout: SyncSender>, stderr: SyncSender>, - exit_status: SyncSender, + status: SyncSender, } struct CommandContext { @@ -203,12 +214,12 @@ impl CommandContext { senders: CommandSenders { stdout: sout, stderr: serr, - exit_status: sexit, + status: sexit, }, receivers: CommandReceivers { stdout: rout, stderr: rerr, - exit_status: rexit, + status: rexit, }, } } @@ -222,30 +233,35 @@ impl Command { pub(crate) fn run(&self) -> Result { use crate::BuiltinCommand::*; use crate::Command::*; + use crate::CommandStatus::*; let (senders, receivers) = CommandContext::new().split(); let CommandSenders { stdout, stderr, - exit_status, + status: status, } = senders; match self { Empty => { - exit_status.send(0)?; + status.send(Code(0))?; } Builtin(EchoText { message }) => { stdout.send(message.bytes().collect())?; stdout.send(b"\n".into())?; - exit_status.send(0)?; + status.send(Code(0))?; } Builtin(Cls) => { let mut stdout_handle = io::stdout(); execute!(stdout_handle, terminal::Clear(terminal::ClearType::All))?; execute!(stdout_handle, cursor::MoveTo(0, 0))?; - exit_status.send(0)?; + status.send(Code(0))?; + } + + Builtin(Exit) => { + status.send(ExitShell)?; } _ => bail!("Command::run not implemented for {:?}", self), @@ -423,6 +439,8 @@ impl Command { "CLS" => Ok(Builtin(Cls)), + "EXIT" => Ok(Builtin(Exit)), + _ => Err(eyre::eyre!("parse not implemented for {:?}", input)), } } -- cgit v1.2.1