From 4cda728b2e6b4d1a9883da654263be0ce5721770 Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Sun, 19 Jan 2025 18:43:03 -0500 Subject: [PATCH] big restructure, all around good changes --- src/lib.rs | 1 - src/ps.rs | 24 ------------------ src/session.rs | 48 +++++++++++++++++++++--------------- src/terminal.rs | 61 ++++++++++++++++++++++------------------------ src/vm/mod.rs | 56 ++++++++++++++++++++---------------------- src/vm/shell.rs | 24 +++++++++--------- src/vm/terminal.rs | 8 +++--- 7 files changed, 100 insertions(+), 122 deletions(-) delete mode 100644 src/ps.rs diff --git a/src/lib.rs b/src/lib.rs index e7b6da0..e541afe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ pub mod session; pub mod commands; pub mod history; pub mod terminal; -pub mod ps; pub mod rc; pub mod vm; diff --git a/src/ps.rs b/src/ps.rs deleted file mode 100644 index ed7753a..0000000 --- a/src/ps.rs +++ /dev/null @@ -1,24 +0,0 @@ -pub const DEFAULT_PS: &str = concat!("pse-", env!("CARGO_PKG_VERSION"), " "); - -pub trait PsMut { - fn get(&self) -> &str; - fn modify(&mut self, prompt: String); -} -impl PsMut for Ps { - #[inline] - fn get(&self) -> &str { - self.0.as_str() - } - #[inline] - fn modify(&mut self, prompt: String) { - self.0 = prompt - } -} - -#[derive(Debug)] -pub struct Ps(String); -impl Ps { - pub const fn set(prompt: String) -> Self { - Self(prompt) - } -} \ No newline at end of file diff --git a/src/session.rs b/src/session.rs index faf79b9..49bc820 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,9 +1,9 @@ +use mlua::Lua as Luau; use std::{cell::RefCell, fs, rc::Rc}; use core::fmt; -use color_print::ceprintln; use crate::{ - history::History, ps::{self, Ps}, rc::{self}, terminal, vm::LuauVm + history::History, rc::{self}, terminal::TermProcessor, vm::LuauVm }; pub trait MapDisplay { @@ -24,28 +24,43 @@ impl MapDisplay for Result { } pub fn shell_error(err: E) { - ceprintln!("[!]: {err}") + color_print::ceprintln!("[!]: {err}") } pub fn shell_error_none(err: E) -> Option { shell_error(err); None } +#[derive(Debug, Clone)] +pub struct VmConfig { + pub sandbox: bool, + pub jit: bool, +} #[derive(Debug, Clone)] pub struct Config { pub norc: bool, - pub nojit: bool, - pub nosandbox: bool + pub vm: VmConfig, } -pub struct LambdaShell { - history: History, - config: Config, - ps: Ps, +pub struct Rt { + pub ps: Rc>, + pub input: String, + pub vm: Luau, } -impl LambdaShell { +pub struct Pse { + pub config: Config, + pub history: History, + pub rt: Rt +} +impl Pse { + const DEFAULT_PS: &str = concat!("pse-", env!("CARGO_PKG_VERSION"), "$ "); + pub fn create(config: Config) -> Self { Self { - ps: Ps::set(ps::DEFAULT_PS.to_owned()), + rt: Rt { + ps: Rc::new(RefCell::new(Self::DEFAULT_PS.to_owned())), + input: String::new(), + vm: Luau::new(), + }, history: History::init(), config, } @@ -56,14 +71,7 @@ impl LambdaShell { if let Some(conf_file) = rc::config_file() { fs::read_to_string(conf_file).map_or_display(|luau_conf| self.vm_exec(luau_conf)); } - } - terminal::Processor::init() - .input_processor(&mut self.history) - .map_or_display(|()| self.history.write_to_file_fallible()); - } - - pub fn vm_exec(&self, source: String) { - let p = Rc::new(RefCell::new(&self.ps)); - LuauVm::new(Rc::clone(p)).exec(source); + }; + self.term_input_processor().map_or_display(|()| self.history.write_to_file_fallible()) } } diff --git a/src/terminal.rs b/src/terminal.rs index e8820a5..8da4316 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -2,7 +2,7 @@ use crossterm::{event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, terminal} use std::io::{self, Write}; use thiserror::Error; -use crate::{commands::Command, history::History, session}; +use crate::{commands::Command, session::{self, Pse}}; #[derive(Debug, Error)] pub enum InputHandleError { @@ -26,10 +26,10 @@ type InputResult = Result; trait SpecificKeybinds { const TERM_ID_1: &str; fn key_ctrl(&mut self, input_key: KeyEvent, keycode: KeyCode) -> InputResult<()>; - fn key_enter(&mut self, history: &mut History) -> InputResult<()>; + fn key_enter(&mut self) -> InputResult<()>; fn key_backspace(&mut self) -> InputResult<()>; } -impl SpecificKeybinds for Processor { +impl SpecificKeybinds for Pse { const TERM_ID_1: &str = "exit"; fn key_ctrl(&mut self, input_key: KeyEvent, keycode: KeyCode) -> InputResult<()> { @@ -39,22 +39,22 @@ impl SpecificKeybinds for Processor { _ => Ok(()) } } else { - self.render(Some(keycode.to_string())) + self.term_render(Some(keycode.to_string())) } } - fn key_enter(&mut self, history: &mut History) -> InputResult<()> { - if self.0 == Self::TERM_ID_1 { return Err(InputHandleError::UserExit) }; + fn key_enter(&mut self) -> InputResult<()> { + if self.rt.input == Self::TERM_ID_1 { return Err(InputHandleError::UserExit) }; terminal::disable_raw_mode().map_err(InputHandleError::DisableRaw)?; - Command::new(&self.0).exec(history); - self.0.clear(); + Command::new(&self.rt.input).exec(&mut self.history); + self.rt.input.clear(); Ok(()) } fn key_backspace(&mut self) -> InputResult<()> { - match self.0.pop() { - Some(_) => self.render(None), + match self.rt.input.pop() { + Some(_) => self.term_render(None), None => { //the string is empty, do terminal beep Ok(()) @@ -63,28 +63,29 @@ impl SpecificKeybinds for Processor { } } -pub struct Processor(String); -impl Processor { - pub const fn init() -> Self { - Self(String::new()) - } - - pub fn render(&mut self, def: Option) -> InputResult<()> { +pub trait TermProcessor { + fn term_render(&mut self, def: Option) -> InputResult<()>; + fn term_input_handler(&mut self, input_key: KeyEvent) -> Option<()>; + fn term_input_mainthread(&mut self) -> io::Result<()>; + fn term_input_processor(&mut self) -> io::Result<()>; +} +impl TermProcessor for Pse { + fn term_render(&mut self, def: Option) -> InputResult<()> { match def { Some(def_string) => { - self.0.push_str(&def_string); + self.rt.input.push_str(&def_string); write!(io::stdout(), "{def_string}").map_err(InputHandleError::Write)?; }, None => { - write!(io::stdout(), "{}", self.0).map_err(InputHandleError::Write)? + write!(io::stdout(), "{}", self.rt.input).map_err(InputHandleError::Write)? } }; io::stdout().flush().map_err(InputHandleError::Flush) } - pub fn input_handler(&mut self, input_key: KeyEvent, history: &mut History) -> Option<()> { + fn term_input_handler(&mut self, input_key: KeyEvent) -> Option<()> { let input_handle = match input_key.code { - KeyCode::Enter => self.key_enter(history), + KeyCode::Enter => self.key_enter(), KeyCode::Backspace => self.key_backspace(), KeyCode::Tab => todo!(), KeyCode::Right => todo!(), @@ -94,28 +95,24 @@ impl Processor { keycode => self.key_ctrl(input_key, keycode) }; input_handle.map_or_else(|inp_err| match inp_err { - InputHandleError::UserExit => None, - InputHandleError::Sigterm => self.render(Some("^C".to_owned())).ok(), - InputHandleError::Write(e) => session::shell_error_none(e), - InputHandleError::Flush(e) => session::shell_error_none(e), - InputHandleError::Key(e) => session::shell_error_none(e), - InputHandleError::DisableRaw(e) => session::shell_error_none(e), - InputHandleError::EnableRaw(e) => session::shell_error_none(e) + InputHandleError::UserExit => None, + InputHandleError::Sigterm => self.term_render(Some("^C".to_owned())).ok(), + input_err => session::shell_error_none(input_err) }, Some) } - fn input_mainthread(&mut self, history: &mut History) -> io::Result<()> { + fn term_input_mainthread(&mut self) -> io::Result<()> { crossterm::execute!(io::stdout(), event::EnableBracketedPaste)?; loop { terminal::enable_raw_mode()?; if let Event::Key(event) = event::read()? { - if self.input_handler(event, history).is_none() { break Ok(()) } + if self.term_input_handler(event).is_none() { break Ok(()) } } } } - pub fn input_processor(&mut self, history: &mut History) -> io::Result<()> { - self.input_mainthread(history)?; + fn term_input_processor(&mut self) -> io::Result<()> { + self.term_input_mainthread()?; terminal::disable_raw_mode()?; crossterm::execute!(io::stdout(), event::DisableBracketedPaste) } diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 667b97d..78bcdbd 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -1,11 +1,10 @@ -use mlua::{Function, Lua as Luau, MultiValue, Result as lResult, Table, Value}; -use color_print::{cformat, ceprintln}; +use mlua::{Function, MultiValue, Result as lResult, Table, Value}; +use color_print::cformat; +use shell::ShellGlobal; use terminal::TerminalGlobal; use core::fmt; -use std::{cell::RefCell, rc::Rc}; -use shell::ShellGlobal; -use crate::{ps::Ps, session::MapDisplay}; +use crate::session::{Pse, MapDisplay}; mod shell; mod terminal; @@ -18,27 +17,27 @@ impl LuauRuntimeErr for Result { #[inline] fn map_or_luau_rt_err Option>(self, f: F) -> Option { self.map_or_else(|luau_rt_err| { - ceprintln!("====\n[!]: {luau_rt_err}\n===="); + color_print::ceprintln!("====\n[!]: {luau_rt_err}\n===="); None }, f) } } -trait Globals { +trait VmGlobals { const LIB_VERSION: &str; const CONV_ERROR: &str; const LIB_NAME: &str; - fn glob_warn(&self, luau_globals: &Table) -> lResult<()>; - fn glob_version(&self, luau_globals: &Table) -> lResult<()>; + fn vm_glob_warn(&self, luau_globals: &Table) -> lResult<()>; + fn vm_glob_version(&self, luau_globals: &Table) -> lResult<()>; } -impl Globals for LuauVm { +impl VmGlobals for Pse { const LIB_VERSION: &str = env!("CARGO_PKG_VERSION"); const LIB_NAME: &str = env!("CARGO_PKG_NAME"); const CONV_ERROR: &str = ""; - fn glob_warn(&self, luau_globals: &Table) -> lResult<()> { + fn vm_glob_warn(&self, luau_globals: &Table) -> lResult<()> { let luau_print = luau_globals.get::("print")?; - luau_globals.raw_set("warn", self.vm.create_function(move |this, args: MultiValue| -> lResult<()> { + luau_globals.raw_set("warn", self.rt.vm.create_function(move |this, args: MultiValue| -> lResult<()> { let luau_multi_values = args.into_iter() .map(|value| cformat!("{}", value.to_string().unwrap_or(Self::CONV_ERROR.to_owned()))) .map(|arg_v| Value::String(this.create_string(arg_v).unwrap())) @@ -48,34 +47,31 @@ impl Globals for LuauVm { })?) } - fn glob_version(&self, luau_globals: &Table) -> lResult<()> { + fn vm_glob_version(&self, luau_globals: &Table) -> lResult<()> { let luau_info = luau_globals.get::("_VERSION")?; luau_globals.raw_set("_VERSION", format!("{luau_info}, {} {}", Self::LIB_NAME, Self::LIB_VERSION)) } } -pub struct LuauVm { - vm: Luau, - ps: Rc> +pub trait LuauVm { + fn vm_setglobs(&self) -> lResult<()>; + fn vm_exec(&self, source: String); } -impl LuauVm { - pub(crate) fn new(ps: Rc>) -> Self { - Self { vm: Luau::new(), ps } - } +impl LuauVm for Pse { + fn vm_setglobs(&self) -> lResult<()> { + let luau_globals = self.rt.vm.globals(); + self.vm_glob_shell(&luau_globals)?; + self.vm_glob_terminal(&luau_globals)?; + self.vm_glob_warn(&luau_globals)?; + self.vm_glob_version(&luau_globals)?; - fn setglobs(&self) -> lResult<()> { - let luau_globals = self.vm.globals(); - self.glob_shell(&luau_globals)?; - self.glob_terminal(&luau_globals)?; - self.glob_warn(&luau_globals)?; - self.glob_version(&luau_globals)?; luau_globals.raw_set("getfenv", mlua::Nil)?; luau_globals.raw_set("setfenv", mlua::Nil)?; - self.vm.sandbox(true)?; - Ok(()) + self.rt.vm.enable_jit(self.config.vm.jit); + self.rt.vm.sandbox(true) } - pub fn exec(&self, source: String) { - self.setglobs().map_or_display_none(|()| self.vm.load(source).exec().map_or_luau_rt_err(Some)); + fn vm_exec(&self, source: String) { + self.vm_setglobs().map_or_display_none(|()| self.rt.vm.load(source).exec().map_or_luau_rt_err(Some)); } } \ No newline at end of file diff --git a/src/vm/shell.rs b/src/vm/shell.rs index 4accc36..8c8f9a8 100644 --- a/src/vm/shell.rs +++ b/src/vm/shell.rs @@ -2,11 +2,11 @@ use mlua::{Lua as Luau, MetaMethod, Result as lResult, Table, UserData, UserData use std::{cell::RefCell, rc::Rc}; use whoami::fallible; -use crate::{ps::{Ps, PsMut}, vm::LuauVm}; - -const DEFAULT_HOSTNAME: &str = "hostname"; +use crate::session::Pse; fn luau_sys_details(luau: &Luau) -> lResult { + const DEFAULT_HOSTNAME: &str = "hostname"; + let system = luau.create_table()?; system.raw_set("DESKTOP_ENV", whoami::desktop_env().to_string())?; system.raw_set("DEVICENAME", whoami::devicename().to_string())?; @@ -19,27 +19,29 @@ fn luau_sys_details(luau: &Luau) -> lResult
{ Ok(system) } -struct Shell(Rc>); +struct Shell(Rc>); impl UserData for Shell { fn add_fields>(fields: &mut F) { - fields.add_field_method_get("PROMPT", |_, this| Ok(this.0.borrow().get().to_owned())); + fields.add_field_method_get("PROMPT", |_, this| Ok(this.0.borrow().to_string())); fields.add_field_method_get("SYSTEM", |luau, _| luau_sys_details(luau)); } fn add_methods>(methods: &mut M) { methods.add_meta_method_mut(MetaMethod::NewIndex, |_, this, (t_index, t_value): (String, String)| -> lResult<()> { - if t_index == "PROMPT" { this.0.borrow_mut().modify(t_value); } + if t_index == "PROMPT" { + let mut prompt = this.0.borrow_mut(); + *prompt = t_value; + } Ok(()) }); } } pub trait ShellGlobal { - fn glob_shell(&self, luau_globals: &Table) -> lResult<()>; + fn vm_glob_shell(&self, luau_globals: &Table) -> lResult<()>; } -impl ShellGlobal for LuauVm { - fn glob_shell(&self, luau_globals: &Table) -> lResult<()> { - luau_globals.raw_set("SHELL", Shell(Rc::clone(&self.ps)))?; - Ok(()) +impl ShellGlobal for Pse { + fn vm_glob_shell(&self, luau_globals: &Table) -> lResult<()> { + luau_globals.raw_set("SHELL", Shell(Rc::clone(&self.rt.ps))) } } \ No newline at end of file diff --git a/src/vm/terminal.rs b/src/vm/terminal.rs index bbd8251..e05088e 100644 --- a/src/vm/terminal.rs +++ b/src/vm/terminal.rs @@ -2,7 +2,7 @@ use mlua::{UserDataFields, Lua as Luau, Result as lResult, Table, UserData}; use const_format::str_split; use crossterm::style::Stylize; -use crate::vm::LuauVm; +use crate::session::Pse; macro_rules! foreground_styles_luau { ($luau:expr, $style_table:expr, $($color:ident)+) => { @@ -84,10 +84,10 @@ impl UserData for Terminal { } pub trait TerminalGlobal { - fn glob_terminal(&self, luau_globals: &Table) -> lResult<()>; + fn vm_glob_terminal(&self, luau_globals: &Table) -> lResult<()>; } -impl TerminalGlobal for LuauVm { - fn glob_terminal(&self, luau_globals: &Table) -> lResult<()> { +impl TerminalGlobal for Pse { + fn vm_glob_terminal(&self, luau_globals: &Table) -> lResult<()> { luau_globals.raw_set("TERMINAL", Terminal) } } \ No newline at end of file