doc/readme #1
5 changed files with 79 additions and 48 deletions
38
src/input.rs
Normal file
38
src/input.rs
Normal file
|
@ -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<usize> = 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<Vec<String>> {
|
||||||
|
if ! self.buffer.is_empty() {
|
||||||
|
Some(parser::parse(&self.buffer))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/job.rs
43
src/job.rs
|
@ -1,28 +1,23 @@
|
||||||
use std::io::Result;
|
use std::process::{
|
||||||
use std::process::{Command, Child, ExitStatus};
|
Command,
|
||||||
|
ExitStatus,
|
||||||
|
};
|
||||||
|
use std::io::{
|
||||||
|
Result,
|
||||||
|
Error,
|
||||||
|
ErrorKind,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Job {
|
pub fn execute(mut argv: Vec<String>) -> Result<ExitStatus> {
|
||||||
id: usize,
|
let mut command = Command::new(&argv[0]);
|
||||||
argv: Vec<String>,
|
argv.remove(0);
|
||||||
is_background: bool,
|
command.args(argv);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_job(argv: &Vec<String>) -> Job {
|
let child = command.spawn();
|
||||||
Job {
|
|
||||||
id: 1,
|
if child.is_ok() {
|
||||||
argv: argv.to_vec(),
|
child.unwrap().wait()
|
||||||
is_background: false,
|
} else {
|
||||||
}
|
Err(Error::new(ErrorKind::Other, "failed to spawn child process"))
|
||||||
}
|
|
||||||
|
|
||||||
impl Job {
|
|
||||||
pub fn execute(&self) -> ExitStatus {
|
|
||||||
let mut argv_iter = self.argv.iter();
|
|
||||||
|
|
||||||
let child_result: Result<Child> = Command::new(argv_iter.next().unwrap())
|
|
||||||
.args(argv_iter)
|
|
||||||
.spawn();
|
|
||||||
|
|
||||||
child_result.unwrap().wait().unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -1,37 +1,26 @@
|
||||||
use std::io;
|
use std::process::exit;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
|
mod input;
|
||||||
|
mod output;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod job;
|
mod job;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut buffer = String::new();
|
let mut buffer = input::Buffer::new();
|
||||||
let mut result_bytes_read: io::Result<usize>;
|
|
||||||
let mut bytes_read: usize = 1;
|
let mut bytes_read: usize = 1;
|
||||||
let mut command_vec: Vec<String>;
|
let mut argv: Option<Vec<String>>;
|
||||||
let mut job: job::Job;
|
|
||||||
|
|
||||||
while bytes_read != 0 {
|
while bytes_read != 0 {
|
||||||
buffer.clear();
|
output::print_ps1();
|
||||||
|
bytes_read = buffer.read_line();
|
||||||
|
|
||||||
print!("$ ");
|
argv = buffer.parse();
|
||||||
if io::stdout().flush().is_err() {
|
if argv.is_some() {
|
||||||
eprintln!("error: can't fully flush stdout or reached EOF");
|
let _ = job::execute(argv.unwrap());
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
9
src/output.rs
Normal file
9
src/output.rs
Normal file
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ fn parse_initial_state(char_splitted_command_line: &mut Vec<char>, current_arg:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_string_in_chars(string_to_split: &String) -> Vec<char> {
|
fn split_string_in_chars(string_to_split: &String) -> Vec<char> {
|
||||||
string_to_split.trim().chars().rev().collect()
|
string_to_split.chars().rev().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(command_line: &String) -> Vec<String> {
|
pub fn parse(command_line: &String) -> Vec<String> {
|
||||||
|
|
Reference in a new issue