From c4559b8aa19a7281407647b05f09637b90c9d699 Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Sat, 28 Dec 2024 23:22:30 -0500 Subject: [PATCH] ladies and gentlemen, we have Luau running --- src/commands.rs | 12 +++++---- src/lib.rs | 5 ++-- src/luau/vm.rs | 67 ++++++++++++++++++++++++++++++++----------------- src/rc.rs | 27 +++++++++++--------- src/shell.rs | 42 ++++++++++++++++++++++++------- 5 files changed, 102 insertions(+), 51 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 4d73f8f..e79563f 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -11,6 +11,11 @@ enum ValidStatus { TryExists(io::Error) } +fn display_none(e: io::Error) -> Option { + println!("{e}"); + None +} + trait PathBufIsValid { fn is_valid(&self) -> Result; fn is_valid_or_home(&self) -> Option; @@ -50,7 +55,7 @@ impl PathBufIsValid for PathBuf { impl ChangeDirectory for Command { fn set_current_dir(&self, new_path: &Path) -> Option { - std::env::set_current_dir(new_path).map_or_else(|cd_err| {println!("{cd_err}"); None}, |()| Some(new_path.to_path_buf())) + std::env::set_current_dir(new_path).map_or_else(|cd_err| display_none(cd_err), |()| Some(new_path.to_path_buf())) } fn home_dir(&self) -> Option { @@ -124,10 +129,7 @@ impl Command { pub fn spawn(&self, command_process: io::Result) -> ProcessExitStatus { match command_process { - Err(e) => { - println!("{e}"); - None - }, + Err(e) => display_none(e), Ok(mut child) => Some(match child.wait() { Ok(exit_status) => exit_status, Err(exit_status_err) => { diff --git a/src/lib.rs b/src/lib.rs index 308e929..38f1e24 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,11 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod shell; - mod commands; mod ps; mod rc; #[path = "./luau/vm.rs"] -mod vm; \ No newline at end of file +mod vm; +#[path = "./luau/alias.rs"] +mod alias; \ No newline at end of file diff --git a/src/luau/vm.rs b/src/luau/vm.rs index ad4d1dc..1b3e359 100644 --- a/src/luau/vm.rs +++ b/src/luau/vm.rs @@ -1,26 +1,33 @@ use mlua::{ Lua as Luau, Result as lResult, - MultiValue + MultiValue, }; +use core::fmt; +use color_print::cprintln; -fn new_instance() -> lResult { - let instance = Luau::new(); - instance.sandbox(true)?; - instance.globals().set("getfenv", mlua::Nil)?; - instance.globals().set("setfenv", mlua::Nil)?; - Ok(instance) +fn display_none(err: E) -> Option +where + E: fmt::Display +{ + println!("{err}"); + None } -fn out(args: MultiValue) -> String { +fn luau_error(err: mlua::Error) -> Option { + cprintln!("====\n{err}\n===="); + None +} + +fn luau_out(luau_args: MultiValue) -> String { let mut print: Vec = Vec::new(); - args.iter() + luau_args.iter() .map(|arg| arg.to_string().unwrap_or("".to_owned())) - .for_each(|v| { + .for_each(|arg| { if !print.is_empty() { - print.push(" ".to_owned()); - } - print.push(v); + print.push('\u{0009}'.to_string()); + }; + print.push(arg); } ); print.concat() @@ -28,31 +35,45 @@ fn out(args: MultiValue) -> String { trait Globals { fn print(&self) -> lResult<()>; + fn printraw(&self) -> lResult<()>; } impl Globals for Vm { fn print(&self) -> lResult<()> { - self.0.globals().set("print", self.0.create_function(|_, args: MultiValue| -> lResult<()> { - color_print::cprintln!("{}", out(args)); + self.0.globals().set("print", self.0.create_function(|_this, args: MultiValue| -> lResult<()> { + cprintln!("{}", luau_out(args)); Ok(()) - })?)?; - self.0.globals().set("printraw", self.0.create_function(|_, args: MultiValue| -> lResult<()> { - println!("{}", out(args)); + })?) + } + fn printraw(&self) -> lResult<()> { + self.0.globals().set("printraw", self.0.create_function(|_this, args: MultiValue| -> lResult<()> { + println!("{}", luau_out(args)); Ok(()) })?) } } -struct Vm(Luau); +pub struct Vm(Luau); impl Vm { pub fn new() -> Option { - new_instance().map_or(None, |l| Some(Self(l))) + let spawn_luau = || -> lResult { + let instance = Luau::new(); + instance.sandbox(true)?; + instance.globals().set("getfenv", mlua::Nil)?; + instance.globals().set("setfenv", mlua::Nil)?; + Ok(instance) + }; + spawn_luau().map_or_else(|e| display_none(e), |l| Some(Self(l))) } fn set_shell_globals(&self) -> mlua::Result<()> { - todo!() + self.print()?; + self.printraw()?; + Ok(()) } - pub fn exec(&self, source: String) -> mlua::Result<()> { - self.set_shell_globals().and(self.0.load(source).exec()) + pub fn exec(&self, source: String) -> Option<()> { + self.set_shell_globals().map_or_else(|e| display_none(e), |()| { + self.0.load(source).exec().map_or_else(|e| luau_error(e), |()| Some(())) + }) } } \ No newline at end of file diff --git a/src/rc.rs b/src/rc.rs index 773b7ef..d8a4eef 100644 --- a/src/rc.rs +++ b/src/rc.rs @@ -25,6 +25,11 @@ enum CreateErr { Passable } +fn display_none(e: io::Error) -> Option { + println!("{e}"); + None +} + #[allow(dead_code)] trait IsValid { fn is_valid(&self, is_dir_or_file: bool) -> Result; @@ -68,10 +73,7 @@ impl IsValid for PathBuf { self.is_valid_or(self.is_dir(), || { match fs::create_dir(self) { Ok(()) => Some(self.to_path_buf()), - Err(create_e) => { - println!("{create_e}"); - None - }, + Err(create_e) => display_none(create_e), } }) } @@ -79,17 +81,11 @@ impl IsValid for PathBuf { fn is_valid_file_or_create(&self, default_file_bytes: &[u8]) -> Option { self.is_valid_or(self.is_file(), || { match File::create(self) { - Err(create_e) => { - println!("{create_e}"); - None - }, Ok(mut file) => match file.write_all(default_file_bytes) { Ok(()) => Some(self.to_path_buf()), - Err(write_e) => { - println!("{write_e}"); - None - }, + Err(write_e) => display_none(write_e), }, + Err(create_e) => display_none(create_e) } }) } @@ -113,6 +109,13 @@ pub fn config_file() -> Option { config_file.is_valid_file_or_create(DEFAULT_CONFIG_CONTENT.as_bytes()) } +//TODO: history.rs +pub fn history_file() -> Option { + let mut config_file = config_dir()?; + config_file.push(".history"); + config_file.is_valid_file_or_create("".as_bytes()) +} + pub fn none() -> Option { None } \ No newline at end of file diff --git a/src/shell.rs b/src/shell.rs index 948fe04..f4050a4 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,21 +1,38 @@ -use crate::{ps, commands, rc}; +use crate::{ps, commands, rc, vm}; use std::{fs, io::{self}}; +use core::fmt; + +fn display_none(err: E) -> Option +where + E: fmt::Display +{ + println!("{err}"); + None +} pub struct Config { pub norc: bool } -pub struct LambdaShell { - terminating: bool, - storage: Storage, - config: Config, -} - struct Storage { pub command_exit_status: commands::ProcessExitStatus, pub ps1: String, } +trait ShellLuauVm { + fn shell_vm_exec(&self, source: String) -> Option<()>; +} +impl ShellLuauVm for LambdaShell { + fn shell_vm_exec(&self, source: String) -> Option<()> { + vm::Vm::new().map_or(None, |vm| vm.exec(source)) + } +} + +pub struct LambdaShell { + terminating: bool, + storage: Storage, + config: Config, +} impl LambdaShell { pub fn create(config: Config) -> Self { Self { @@ -47,11 +64,18 @@ impl LambdaShell { }) } - pub fn start(&mut self) { - let rc_file = match self.config.norc { + fn rc_parse(&self) { + let rc_file = match self.config.norc { true => rc::none(), false => rc::config_file(), }; + rc_file.map(|conf_file| fs::read_to_string(conf_file) + .map_or_else(|read_err| display_none(read_err), |conf| self.shell_vm_exec(conf)) + ); + } + + pub fn start(&mut self) { + self.rc_parse(); ps::display(&self.storage.ps1);