diff options
author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-30 20:22:36 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-30 20:22:46 +0200 |
commit | 9e41cdfb69532c51be5a241c975cec023b8d858b (patch) | |
tree | 23df34492edaa4eb23e11472958f801cace33166 | |
parent | 5a4f8de935872076e71c124de599ff88026e550d (diff) |
Implement EXIT.
-rw-r--r-- | src/main.rs | 40 |
1 files changed, 29 insertions, 11 deletions
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<Vec<u8>>, stderr: Receiver<Vec<u8>>, - exit_status: Receiver<u16>, + status: Receiver<CommandStatus>, } struct CommandSenders { stdout: SyncSender<Vec<u8>>, stderr: SyncSender<Vec<u8>>, - exit_status: SyncSender<u16>, + status: SyncSender<CommandStatus>, } 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<CommandReceivers> { 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)), } } |