Merge pull request 'feature/variables' (#3) from feature/variables into main
Reviewed-on: https://gitea.ahur.ac/ahurac/rash/pulls/3
This commit is contained in:
commit
69dd46a039
6 changed files with 62 additions and 26 deletions
|
@ -17,6 +17,7 @@
|
||||||
- [ ] `exit`
|
- [ ] `exit`
|
||||||
- [ ] Special variables
|
- [ ] Special variables
|
||||||
- [ ] `_`
|
- [ ] `_`
|
||||||
- [ ] `PS1`
|
- [x] `PS1`
|
||||||
- [ ] Positional variables
|
- [ ] Positional variables
|
||||||
|
- [ ] `RANDOM`
|
||||||
- [ ] Handle signals
|
- [ ] Handle signals
|
||||||
|
|
10
src/input.rs
10
src/input.rs
|
@ -1,15 +1,20 @@
|
||||||
use std::io as stdio;
|
use std::io as stdio;
|
||||||
use stdio::stdin;
|
use stdio::stdin;
|
||||||
use crate::parser;
|
use crate::parser;
|
||||||
|
use crate::job;
|
||||||
|
use std::process::ExitStatus;
|
||||||
|
use std::io::Result;
|
||||||
|
|
||||||
pub struct Buffer {
|
pub struct Buffer {
|
||||||
buffer: String,
|
buffer: String,
|
||||||
|
argv: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buffer {
|
impl Buffer {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
buffer: String::new(),
|
buffer: String::new(),
|
||||||
|
argv: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +33,10 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&self) -> Option<Vec<String>> {
|
pub fn try_spawn(&mut self) -> Option<Result<ExitStatus>> {
|
||||||
if ! self.buffer.is_empty() {
|
if ! self.buffer.is_empty() {
|
||||||
Some(parser::parse(&self.buffer))
|
self.argv = parser::parse(&self.buffer);
|
||||||
|
Some(job::execute(&mut self.argv))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::io::{
|
||||||
ErrorKind,
|
ErrorKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn execute(mut argv: Vec<String>) -> Result<ExitStatus> {
|
pub fn execute(argv: &mut Vec<String>) -> Result<ExitStatus> {
|
||||||
let mut command = Command::new(&argv[0]);
|
let mut command = Command::new(&argv[0]);
|
||||||
argv.remove(0);
|
argv.remove(0);
|
||||||
command.args(argv);
|
command.args(argv);
|
||||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -1,36 +1,35 @@
|
||||||
|
mod input;
|
||||||
|
mod parser;
|
||||||
|
mod job;
|
||||||
|
mod variables;
|
||||||
|
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
use std::process::{
|
use std::process::{
|
||||||
ExitStatus,
|
ExitStatus,
|
||||||
exit,
|
exit,
|
||||||
};
|
};
|
||||||
|
use variables::Variables;
|
||||||
mod input;
|
|
||||||
mod output;
|
|
||||||
mod parser;
|
|
||||||
mod job;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut buffer = input::Buffer::new();
|
let mut buffer = input::Buffer::new();
|
||||||
let mut bytes_read: usize = 1;
|
let mut bytes_read: usize = 1;
|
||||||
let mut argv: Option<Vec<String>>;
|
let mut exit_status: Option<Result<ExitStatus>>;
|
||||||
let mut exit_status: Result<ExitStatus>;
|
|
||||||
let mut exit_code: i32 = 0;
|
let mut exit_code: i32 = 0;
|
||||||
|
let mut variables = Variables::new();
|
||||||
|
|
||||||
while bytes_read != 0 {
|
while bytes_read != 0 {
|
||||||
output::print_ps1();
|
variables.print_ps1();
|
||||||
bytes_read = buffer.read_line();
|
bytes_read = buffer.read_line();
|
||||||
|
|
||||||
argv = buffer.parse();
|
exit_status = buffer.try_spawn();
|
||||||
if argv.is_some() {
|
|
||||||
exit_status = job::execute(argv.unwrap());
|
|
||||||
|
|
||||||
|
if exit_status.is_some() {
|
||||||
|
let exit_status = exit_status.unwrap();
|
||||||
if exit_status.is_ok() {
|
if exit_status.is_ok() {
|
||||||
let exit_status = exit_status.unwrap();
|
let exit_status = exit_status.unwrap();
|
||||||
|
|
||||||
if exit_status.code().is_some() {
|
if exit_status.code().is_some() {
|
||||||
exit_code = exit_status.code().unwrap();
|
exit_code = exit_status.code().unwrap();
|
||||||
} else {
|
|
||||||
exit_code = 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exit_code = 1;
|
exit_code = 1;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
39
src/variables.rs
Normal file
39
src/variables.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
pub struct Variables {
|
||||||
|
variables: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variables {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
variables: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> String {
|
||||||
|
let content = env::var(name);
|
||||||
|
|
||||||
|
if content.is_ok() {
|
||||||
|
content.unwrap()
|
||||||
|
} else {
|
||||||
|
let content = self.variables.get(name);
|
||||||
|
|
||||||
|
if content.is_some() {
|
||||||
|
content.unwrap().to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_ps1(&self) {
|
||||||
|
print!("{}", self.get("PS1"));
|
||||||
|
if io::stdout().flush().is_err() {
|
||||||
|
eprintln!("error: can't fully flush stdout or reached EOF");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue