ladies and gentlemen, we have Luau running
This commit is contained in:
parent
03a5b064e5
commit
c4559b8aa1
@ -11,6 +11,11 @@ enum ValidStatus {
|
|||||||
TryExists(io::Error)
|
TryExists(io::Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_none<T>(e: io::Error) -> Option<T> {
|
||||||
|
println!("{e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
trait PathBufIsValid {
|
trait PathBufIsValid {
|
||||||
fn is_valid(&self) -> Result<PathBuf, ValidStatus>;
|
fn is_valid(&self) -> Result<PathBuf, ValidStatus>;
|
||||||
fn is_valid_or_home(&self) -> Option<PathBuf>;
|
fn is_valid_or_home(&self) -> Option<PathBuf>;
|
||||||
@ -50,7 +55,7 @@ impl PathBufIsValid for PathBuf {
|
|||||||
|
|
||||||
impl ChangeDirectory for Command {
|
impl ChangeDirectory for Command {
|
||||||
fn set_current_dir(&self, new_path: &Path) -> Option<PathBuf> {
|
fn set_current_dir(&self, new_path: &Path) -> Option<PathBuf> {
|
||||||
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<PathBuf> {
|
fn home_dir(&self) -> Option<PathBuf> {
|
||||||
@ -124,10 +129,7 @@ impl Command {
|
|||||||
|
|
||||||
pub fn spawn(&self, command_process: io::Result<process::Child>) -> ProcessExitStatus {
|
pub fn spawn(&self, command_process: io::Result<process::Child>) -> ProcessExitStatus {
|
||||||
match command_process {
|
match command_process {
|
||||||
Err(e) => {
|
Err(e) => display_none(e),
|
||||||
println!("{e}");
|
|
||||||
None
|
|
||||||
},
|
|
||||||
Ok(mut child) => Some(match child.wait() {
|
Ok(mut child) => Some(match child.wait() {
|
||||||
Ok(exit_status) => exit_status,
|
Ok(exit_status) => exit_status,
|
||||||
Err(exit_status_err) => {
|
Err(exit_status_err) => {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod ps;
|
mod ps;
|
||||||
mod rc;
|
mod rc;
|
||||||
|
|
||||||
#[path = "./luau/vm.rs"]
|
#[path = "./luau/vm.rs"]
|
||||||
mod vm;
|
mod vm;
|
||||||
|
#[path = "./luau/alias.rs"]
|
||||||
|
mod alias;
|
@ -1,26 +1,33 @@
|
|||||||
use mlua::{
|
use mlua::{
|
||||||
Lua as Luau,
|
Lua as Luau,
|
||||||
Result as lResult,
|
Result as lResult,
|
||||||
MultiValue
|
MultiValue,
|
||||||
};
|
};
|
||||||
|
use core::fmt;
|
||||||
|
use color_print::cprintln;
|
||||||
|
|
||||||
fn new_instance() -> lResult<Luau> {
|
fn display_none<T, E>(err: E) -> Option<T>
|
||||||
let instance = Luau::new();
|
where
|
||||||
instance.sandbox(true)?;
|
E: fmt::Display
|
||||||
instance.globals().set("getfenv", mlua::Nil)?;
|
{
|
||||||
instance.globals().set("setfenv", mlua::Nil)?;
|
println!("{err}");
|
||||||
Ok(instance)
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn out(args: MultiValue) -> String {
|
fn luau_error<T>(err: mlua::Error) -> Option<T> {
|
||||||
|
cprintln!("<bold>====</>\n<r>{err}</>\n<bold>====</>");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn luau_out(luau_args: MultiValue) -> String {
|
||||||
let mut print: Vec<String> = Vec::new();
|
let mut print: Vec<String> = Vec::new();
|
||||||
args.iter()
|
luau_args.iter()
|
||||||
.map(|arg| arg.to_string().unwrap_or("<SHELL CONVERSION ERROR>".to_owned()))
|
.map(|arg| arg.to_string().unwrap_or("<SHELL CONVERSION ERROR>".to_owned()))
|
||||||
.for_each(|v| {
|
.for_each(|arg| {
|
||||||
if !print.is_empty() {
|
if !print.is_empty() {
|
||||||
print.push(" ".to_owned());
|
print.push('\u{0009}'.to_string());
|
||||||
}
|
};
|
||||||
print.push(v);
|
print.push(arg);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
print.concat()
|
print.concat()
|
||||||
@ -28,31 +35,45 @@ fn out(args: MultiValue) -> String {
|
|||||||
|
|
||||||
trait Globals {
|
trait Globals {
|
||||||
fn print(&self) -> lResult<()>;
|
fn print(&self) -> lResult<()>;
|
||||||
|
fn printraw(&self) -> lResult<()>;
|
||||||
}
|
}
|
||||||
impl Globals for Vm {
|
impl Globals for Vm {
|
||||||
fn print(&self) -> lResult<()> {
|
fn print(&self) -> lResult<()> {
|
||||||
self.0.globals().set("print", self.0.create_function(|_, args: MultiValue| -> lResult<()> {
|
self.0.globals().set("print", self.0.create_function(|_this, args: MultiValue| -> lResult<()> {
|
||||||
color_print::cprintln!("{}", out(args));
|
cprintln!("{}", luau_out(args));
|
||||||
Ok(())
|
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(())
|
Ok(())
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Vm(Luau);
|
pub struct Vm(Luau);
|
||||||
impl Vm {
|
impl Vm {
|
||||||
pub fn new() -> Option<Self> {
|
pub fn new() -> Option<Self> {
|
||||||
new_instance().map_or(None, |l| Some(Self(l)))
|
let spawn_luau = || -> lResult<Luau> {
|
||||||
|
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<()> {
|
fn set_shell_globals(&self) -> mlua::Result<()> {
|
||||||
todo!()
|
self.print()?;
|
||||||
|
self.printraw()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(&self, source: String) -> mlua::Result<()> {
|
pub fn exec(&self, source: String) -> Option<()> {
|
||||||
self.set_shell_globals().and(self.0.load(source).exec())
|
self.set_shell_globals().map_or_else(|e| display_none(e), |()| {
|
||||||
|
self.0.load(source).exec().map_or_else(|e| luau_error(e), |()| Some(()))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
27
src/rc.rs
27
src/rc.rs
@ -25,6 +25,11 @@ enum CreateErr {
|
|||||||
Passable
|
Passable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_none<T>(e: io::Error) -> Option<T> {
|
||||||
|
println!("{e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
trait IsValid {
|
trait IsValid {
|
||||||
fn is_valid(&self, is_dir_or_file: bool) -> Result<PathBuf, IsValidDirErr>;
|
fn is_valid(&self, is_dir_or_file: bool) -> Result<PathBuf, IsValidDirErr>;
|
||||||
@ -68,10 +73,7 @@ impl IsValid for PathBuf {
|
|||||||
self.is_valid_or(self.is_dir(), || {
|
self.is_valid_or(self.is_dir(), || {
|
||||||
match fs::create_dir(self) {
|
match fs::create_dir(self) {
|
||||||
Ok(()) => Some(self.to_path_buf()),
|
Ok(()) => Some(self.to_path_buf()),
|
||||||
Err(create_e) => {
|
Err(create_e) => display_none(create_e),
|
||||||
println!("{create_e}");
|
|
||||||
None
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -79,17 +81,11 @@ impl IsValid for PathBuf {
|
|||||||
fn is_valid_file_or_create(&self, default_file_bytes: &[u8]) -> Option<PathBuf> {
|
fn is_valid_file_or_create(&self, default_file_bytes: &[u8]) -> Option<PathBuf> {
|
||||||
self.is_valid_or(self.is_file(), || {
|
self.is_valid_or(self.is_file(), || {
|
||||||
match File::create(self) {
|
match File::create(self) {
|
||||||
Err(create_e) => {
|
|
||||||
println!("{create_e}");
|
|
||||||
None
|
|
||||||
},
|
|
||||||
Ok(mut file) => match file.write_all(default_file_bytes) {
|
Ok(mut file) => match file.write_all(default_file_bytes) {
|
||||||
Ok(()) => Some(self.to_path_buf()),
|
Ok(()) => Some(self.to_path_buf()),
|
||||||
Err(write_e) => {
|
Err(write_e) => display_none(write_e),
|
||||||
println!("{write_e}");
|
|
||||||
None
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
Err(create_e) => display_none(create_e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -113,6 +109,13 @@ pub fn config_file() -> Option<PathBuf> {
|
|||||||
config_file.is_valid_file_or_create(DEFAULT_CONFIG_CONTENT.as_bytes())
|
config_file.is_valid_file_or_create(DEFAULT_CONFIG_CONTENT.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: history.rs
|
||||||
|
pub fn history_file() -> Option<PathBuf> {
|
||||||
|
let mut config_file = config_dir()?;
|
||||||
|
config_file.push(".history");
|
||||||
|
config_file.is_valid_file_or_create("".as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn none() -> Option<PathBuf> {
|
pub fn none() -> Option<PathBuf> {
|
||||||
None
|
None
|
||||||
}
|
}
|
42
src/shell.rs
42
src/shell.rs
@ -1,21 +1,38 @@
|
|||||||
use crate::{ps, commands, rc};
|
use crate::{ps, commands, rc, vm};
|
||||||
use std::{fs, io::{self}};
|
use std::{fs, io::{self}};
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
fn display_none<T, E>(err: E) -> Option<T>
|
||||||
|
where
|
||||||
|
E: fmt::Display
|
||||||
|
{
|
||||||
|
println!("{err}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub norc: bool
|
pub norc: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LambdaShell {
|
|
||||||
terminating: bool,
|
|
||||||
storage: Storage,
|
|
||||||
config: Config,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Storage {
|
struct Storage {
|
||||||
pub command_exit_status: commands::ProcessExitStatus,
|
pub command_exit_status: commands::ProcessExitStatus,
|
||||||
pub ps1: String,
|
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 {
|
impl LambdaShell {
|
||||||
pub fn create(config: Config) -> Self {
|
pub fn create(config: Config) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -47,11 +64,18 @@ impl LambdaShell {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) {
|
fn rc_parse(&self) {
|
||||||
let rc_file = match self.config.norc {
|
let rc_file = match self.config.norc {
|
||||||
true => rc::none(),
|
true => rc::none(),
|
||||||
false => rc::config_file(),
|
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);
|
ps::display(&self.storage.ps1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user