libpse/src/shell.rs

82 lines
1.7 KiB
Rust

use crate::{ps, commands, rc, vm};
use std::{fs, io::{self}};
pub struct Config {
pub norc: bool
}
struct Storage {
pub command_exit_status: commands::ProcessExitStatus,
pub ps1: String,
}
trait ShellLuauVm {
fn shell_vm_exec(&self, source: String);
}
impl ShellLuauVm for LambdaShell {
fn shell_vm_exec(&self, source: String) {
vm::Vm::new().exec(source);
}
}
pub struct LambdaShell {
terminating: bool,
storage: Storage,
config: Config,
}
impl LambdaShell {
pub fn create(config: Config) -> Self {
Self {
storage: Storage {
command_exit_status: None,
ps1: ps::DEFAULT_PS.to_owned(),
},
terminating: false,
config,
}
}
pub fn wait(&mut self) -> Result<(), io::Error> {
io::Write::flush(&mut io::stdout()).map_or_else(|flush_error| Err(flush_error), |()| {
let mut input = String::new();
io::stdin().read_line(&mut input).map_or_else(|read_error| println!("{read_error}"), |_size| {
let trimmed_input = input.trim();
match trimmed_input {
//special casey
"exit" => self.terminating = true,
_ => self.storage.command_exit_status = commands::Command::new(trimmed_input.to_owned()).exec()
};
});
Ok(())
})
}
fn rc_parse(&self) {
if !self.config.norc {
rc::config_file().map(|conf_file| fs::read_to_string(conf_file).map_or_else(
|read_err| println!("{read_err}"),
|luau_conf| self.shell_vm_exec(luau_conf)
));
}
}
pub fn start(&mut self) {
self.rc_parse();
ps::display(&self.storage.ps1);
loop {
match self.terminating {
true => break,
false => match self.wait() {
Ok(()) => ps::display(&self.storage.ps1),
Err(flush_error) => {
println!("{flush_error}");
break;
}
},
}
}
}
}