diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..93ac102 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,38 @@ +use std::io as stdio; +use stdio::stdin; +use crate::parser; + +pub struct Buffer { + buffer: String, +} + +impl Buffer { + pub fn new() -> Self { + Self { + buffer: String::new(), + } + } + + pub fn read_line(&mut self) -> usize { + self.buffer.clear(); + + let result: stdio::Result = stdin().read_line(&mut self.buffer); + + if result.is_err() { + eprintln!("error: invalid UTF-8 characters were read"); + self.buffer.clear(); + 1 + } else { + self.buffer = self.buffer.trim().to_string(); + result.unwrap() + } + } + + pub fn parse(&self) -> Option> { + if ! self.buffer.is_empty() { + Some(parser::parse(&self.buffer)) + } else { + None + } + } +} diff --git a/src/job.rs b/src/job.rs index 3177ee4..028ed75 100644 --- a/src/job.rs +++ b/src/job.rs @@ -1,28 +1,23 @@ -use std::io::Result; -use std::process::{Command, Child, ExitStatus}; +use std::process::{ + Command, + ExitStatus, +}; +use std::io::{ + Result, + Error, + ErrorKind, +}; -pub struct Job { - id: usize, - argv: Vec, - is_background: bool, -} +pub fn execute(mut argv: Vec) -> Result { + let mut command = Command::new(&argv[0]); + argv.remove(0); + command.args(argv); -pub fn build_job(argv: &Vec) -> Job { - Job { - id: 1, - argv: argv.to_vec(), - is_background: false, - } -} - -impl Job { - pub fn execute(&self) -> ExitStatus { - let mut argv_iter = self.argv.iter(); - - let child_result: Result = Command::new(argv_iter.next().unwrap()) - .args(argv_iter) - .spawn(); - - child_result.unwrap().wait().unwrap() + let child = command.spawn(); + + if child.is_ok() { + child.unwrap().wait() + } else { + Err(Error::new(ErrorKind::Other, "failed to spawn child process")) } } diff --git a/src/main.rs b/src/main.rs index d273a5e..13dd9f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,37 +1,26 @@ -use std::io; -use std::io::Write; +use std::process::exit; +mod input; +mod output; mod parser; mod job; fn main() { - let mut buffer = String::new(); - let mut result_bytes_read: io::Result; + let mut buffer = input::Buffer::new(); let mut bytes_read: usize = 1; - let mut command_vec: Vec; - let mut job: job::Job; + let mut argv: Option>; while bytes_read != 0 { - buffer.clear(); + output::print_ps1(); + bytes_read = buffer.read_line(); - print!("$ "); - if io::stdout().flush().is_err() { - eprintln!("error: can't fully flush stdout or reached EOF"); - } - result_bytes_read = io::stdin().read_line(&mut buffer); - - if result_bytes_read.is_err() { - eprintln!("error: invalid UTF-8 characters were read"); - bytes_read = 1; - } else { - bytes_read = result_bytes_read.unwrap(); - if bytes_read != 0 { - command_vec = parser::parse(&buffer); - job = job::build_job(&command_vec); - job.execute(); - } + argv = buffer.parse(); + if argv.is_some() { + let _ = job::execute(argv.unwrap()); } } println!(); + + exit(0); } diff --git a/src/output.rs b/src/output.rs new file mode 100644 index 0000000..3888585 --- /dev/null +++ b/src/output.rs @@ -0,0 +1,9 @@ +use std::io::stdout; +use std::io::Write; + +pub fn print_ps1() { + print!("$ "); + if stdout().flush().is_err() { + eprintln!("error: can't fully flush stdout or reached EOF"); + } +} diff --git a/src/parser.rs b/src/parser.rs index 3824914..97a4bf6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -33,7 +33,7 @@ fn parse_initial_state(char_splitted_command_line: &mut Vec, current_arg: } fn split_string_in_chars(string_to_split: &String) -> Vec { - string_to_split.trim().chars().rev().collect() + string_to_split.chars().rev().collect() } pub fn parse(command_line: &String) -> Vec {