From 4338ddffafffe7c41bd9c1a3da46b2910a14a212 Mon Sep 17 00:00:00 2001 From: Ahurac Date: Thu, 11 Apr 2024 10:16:09 +0200 Subject: [PATCH] command : modularisation --- src/command/command_sequence.rs | 36 ++++++++++++ src/command/mod.rs | 98 +-------------------------------- src/command/unix_program.rs | 46 ++++++++++++++++ src/control.rs | 3 +- src/exit_code.rs | 17 ++++++ src/main.rs | 1 + src/parser.rs | 3 +- 7 files changed, 107 insertions(+), 97 deletions(-) create mode 100644 src/command/command_sequence.rs create mode 100644 src/command/unix_program.rs create mode 100644 src/exit_code.rs diff --git a/src/command/command_sequence.rs b/src/command/command_sequence.rs new file mode 100644 index 0000000..2950dc3 --- /dev/null +++ b/src/command/command_sequence.rs @@ -0,0 +1,36 @@ +use crate::command::Command; +use crate::exit_code::ExitCode; + +pub struct CommandSequence { + command: Box, + next_command: Option>, +} + +impl CommandSequence { + pub fn new(command: impl Command + 'static) -> Self { + Self { + command: Box::new(command), + next_command: None, + } + } + + pub fn add(&mut self, command: impl Command + 'static) { + if self.next_command.is_none() { + self.next_command = Some(Box::new(CommandSequence::new(command))); + } else { + self.next_command.as_mut().unwrap().add(command); + } + } +} + +impl Command for CommandSequence { + fn spawn(&mut self) -> ExitCode { + let mut exit_code = self.command.spawn(); + + if self.next_command.is_some() { + exit_code = self.next_command.as_mut().unwrap().spawn(); + } + + exit_code + } +} diff --git a/src/command/mod.rs b/src/command/mod.rs index 1634de3..1bd7b37 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -1,100 +1,8 @@ -use crate::error; +pub mod command_sequence; +pub mod unix_program; -pub struct ExitCode { - exit_code: u8, -} - -impl ExitCode { - pub fn new(exit_code: u8) -> Self { - Self { exit_code } - } - - pub fn get(&self) -> u8 { - self.exit_code - } - - pub fn not_found() -> Self { - Self { exit_code: 127 } - } -} +use crate::exit_code::ExitCode; pub trait Command { fn spawn(&mut self) -> ExitCode; } - -pub struct CommandSequence { - command: Box, - next_command: Option>, -} - -impl CommandSequence { - pub fn new(command: impl Command + 'static) -> Self { - Self { - command: Box::new(command), - next_command: None, - } - } - - pub fn add(&mut self, command: impl Command + 'static) { - if self.next_command.is_none() { - self.next_command = Some(Box::new(CommandSequence::new(command))); - } else { - self.next_command.as_mut().unwrap().add(command); - } - } -} - -impl Command for CommandSequence { - fn spawn(&mut self) -> ExitCode { - let mut exit_code = self.command.spawn(); - - if self.next_command.is_some() { - exit_code = self.next_command.as_mut().unwrap().spawn(); - } - - exit_code - } -} - -pub struct UnixProgram { - command: std::process::Command, -} - -impl UnixProgram { - pub fn new(mut argv: Vec) -> Self { - let program = argv.remove(0); - let mut command = std::process::Command::new(&program); - command.args(argv); - - Self { command } - } -} - -impl Command for UnixProgram { - fn spawn(&mut self) -> ExitCode { - let handle = self.command.spawn(); - - if handle.is_ok() { - let exit_code = handle - .unwrap() - .wait() - .expect("error waiting for the child") - .code() - .unwrap_or(1); - - let exit_code = match u8::try_from(exit_code) { - Ok(code) => ExitCode::new(code), - Err(_e) => ExitCode::new(u8::MAX), - }; - - exit_code - } else { - let message = format!( - "{}: command not found", - self.command.get_program().to_str().unwrap() - ); - error::print_error(message); - ExitCode::not_found() - } - } -} diff --git a/src/command/unix_program.rs b/src/command/unix_program.rs new file mode 100644 index 0000000..4a1b5c0 --- /dev/null +++ b/src/command/unix_program.rs @@ -0,0 +1,46 @@ +use crate::command::Command; +use crate::error::print_error; +use crate::exit_code::ExitCode; + +pub struct UnixProgram { + command: std::process::Command, +} + +impl UnixProgram { + pub fn new(mut argv: Vec) -> Self { + let program = argv.remove(0); + let mut command = std::process::Command::new(&program); + command.args(argv); + + Self { command } + } +} + +impl Command for UnixProgram { + fn spawn(&mut self) -> ExitCode { + let handle = self.command.spawn(); + + if handle.is_ok() { + let exit_code = handle + .unwrap() + .wait() + .expect("error waiting for the child") + .code() + .unwrap_or(1); + + let exit_code = match u8::try_from(exit_code) { + Ok(code) => ExitCode::new(code), + Err(_e) => ExitCode::new(u8::MAX), + }; + + exit_code + } else { + let message = format!( + "{}: command not found", + self.command.get_program().to_str().unwrap() + ); + print_error(message); + ExitCode::not_found() + } + } +} diff --git a/src/control.rs b/src/control.rs index 3e0f617..86c0a2e 100644 --- a/src/control.rs +++ b/src/control.rs @@ -1,4 +1,5 @@ -use crate::command::{Command, ExitCode}; +use crate::command::Command; +use crate::exit_code::ExitCode; use crate::interface::{get_user_input, print_prompt}; use crate::parser::parse_command_line; diff --git a/src/exit_code.rs b/src/exit_code.rs new file mode 100644 index 0000000..9ee70d5 --- /dev/null +++ b/src/exit_code.rs @@ -0,0 +1,17 @@ +pub struct ExitCode { + exit_code: u8, +} + +impl ExitCode { + pub fn new(exit_code: u8) -> Self { + Self { exit_code } + } + + pub fn get(&self) -> u8 { + self.exit_code + } + + pub fn not_found() -> Self { + Self { exit_code: 127 } + } +} diff --git a/src/main.rs b/src/main.rs index fd3fe96..568876e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod command; mod control; mod error; +mod exit_code; mod interface; mod parser; diff --git a/src/parser.rs b/src/parser.rs index 9d586c4..361d006 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,5 @@ -use crate::command::{CommandSequence, UnixProgram}; +use crate::command::command_sequence::CommandSequence; +use crate::command::unix_program::UnixProgram; pub fn parse_command_line(line: String) -> Option { let argv: Vec = line.split_whitespace().map(|s| s.to_string()).collect();