improve error handling and add metadata

This commit is contained in:
Chance 2025-04-03 01:00:24 -04:00 committed by BitSyndicate
parent 87cef23366
commit b8d5c09d08
Signed by: bitsyndicate
GPG key ID: 443E4198D6BBA6DE
17 changed files with 1162 additions and 787 deletions

View file

@ -1,18 +1,17 @@
use std::{fs, path::PathBuf, str::FromStr};
use anyhow::anyhow;
use parking_lot::RwLock;
use regex::Regex;
use super::{handler::Command, input::tokenize};
use crate::core::repl::handler::COMMAND_MANAGER;
use crate::error::{ZenyxError,ZenyxErrorKind};
#[derive(Default)]
pub struct HelpCommand;
impl Command for HelpCommand {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), ZenyxError> {
let manager = COMMAND_MANAGER.read();
println!("Available commands:\n");
@ -55,11 +54,12 @@ impl Command for HelpCommand {
String::from("Help")
}
}
#[derive(Default)]
pub struct ClearCommand;
impl Command for ClearCommand {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), ZenyxError> {
println!("Clearing screen..., running command");
let _result = if cfg!(target_os = "windows") {
std::process::Command::new("cmd")
@ -96,12 +96,16 @@ impl Command for ClearCommand {
pub struct ExitCommand;
impl Command for ExitCommand {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), ZenyxError> {
match args {
Some(args) => {
let exit_code = args[0].parse()?;
let exit_code = args[0].parse().map_err(|e| {
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Failed to parse exit code")
.with_source(e)
.build()
})?;
std::process::exit(exit_code);
// Ok(())
}
None => {
std::process::exit(0);
@ -133,18 +137,31 @@ impl Command for ExitCommand {
String::from("None")
}
}
#[derive(Default)]
pub struct ExecFile;
impl Command for ExecFile {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), ZenyxError> {
match args {
Some(args) => {
let file_path = PathBuf::from_str(&args[0])?;
let file_path = PathBuf::from_str(&args[0]).map_err(|e| {
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Invalid file path")
.with_source(e)
.build()
})?;
if file_path.extension().is_some() && file_path.extension().unwrap() != "zensh" {
return Err(anyhow!("Selected file was not a zensh file"));
return Err(ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Selected file was not a zensh file")
.build());
} else {
let zscript = fs::read_to_string(file_path)?;
let zscript = fs::read_to_string(file_path).map_err(|e| {
ZenyxError::builder(ZenyxErrorKind::Io)
.with_message("Failed to read file")
.with_source(e)
.build()
})?;
if let Ok(command) = eval(zscript) {
println!("{:#?}", command);
for (cmd_name, cmd_args) in command {
@ -163,7 +180,9 @@ impl Command for ExecFile {
}
Ok(())
}
None => Err(anyhow!("Not enough argumentss")),
None => Err(ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Not enough arguments")
.build()),
}
}
@ -194,7 +213,7 @@ pub struct CounterCommand {
}
impl Command for CounterCommand {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, _args: Option<Vec<String>>) -> Result<(), ZenyxError> {
// Increment the counter
let mut count = self.counter.write();
*count += 1;
@ -226,10 +245,11 @@ impl Command for CounterCommand {
String::from("count")
}
}
#[derive(Default)]
pub struct PanicCommmand;
impl Command for PanicCommmand {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), anyhow::Error> {
fn execute(&self, args: Option<Vec<String>>) -> Result<(), ZenyxError> {
if args.is_some() {
let panic_msg = &args.unwrap()[0];
panic!("{}", panic_msg)
@ -260,12 +280,19 @@ impl Command for PanicCommmand {
}
}
fn eval(input: String) -> Result<Vec<(String, Option<Vec<String>>)>, anyhow::Error> {
fn eval(input: String) -> Result<Vec<(String, Option<Vec<String>>)>, ZenyxError> {
if input.trim().is_empty() {
return Err(anyhow!("Input was empty"));
return Err(ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Input was empty")
.build());
}
let pattern = Regex::new(r"[;|\n]").unwrap();
let pattern = Regex::new(r"[;|\n]").map_err(|e| {
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
.with_message("Failed to compile regex")
.with_source(e)
.build()
})?;
let commands: Vec<&str> = pattern.split(&input).collect();
let mut evaluted = vec![];