forked from nonsensical-dev/zenyx-engine
build: remove regex dependency in favor of rust iterators
This commit is contained in:
parent
29f1cf68bf
commit
7c3fa95566
5 changed files with 90 additions and 75 deletions
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -46,15 +46,6 @@ dependencies = [
|
||||||
"zerocopy 0.7.35",
|
"zerocopy 0.7.35",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aligned-vec"
|
name = "aligned-vec"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -2458,35 +2449,6 @@ dependencies = [
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-automata",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-automata"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -4177,7 +4139,6 @@ dependencies = [
|
||||||
"native-dialog",
|
"native-dialog",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
"regex",
|
|
||||||
"rustyline",
|
"rustyline",
|
||||||
"serde",
|
"serde",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
|
|
|
@ -13,7 +13,6 @@ chrono = "0.4.39"
|
||||||
colored = "3.0.0"
|
colored = "3.0.0"
|
||||||
parking_lot.workspace = true
|
parking_lot.workspace = true
|
||||||
# TBR (if possible)
|
# TBR (if possible)
|
||||||
regex = "1.11.1"
|
|
||||||
rustyline = { version = "15.0.0", features = ["derive", "rustyline-derive"] }
|
rustyline = { version = "15.0.0", features = ["derive", "rustyline-derive"] }
|
||||||
thiserror = "2.0.11"
|
thiserror = "2.0.11"
|
||||||
# Tokio is heavy but so far its the best option, we should make better use of it or switch to another runtime.
|
# Tokio is heavy but so far its the best option, we should make better use of it or switch to another runtime.
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::{error::Error, path::PathBuf};
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use native_dialog::{MessageDialog, MessageType};
|
use native_dialog::{MessageDialog, MessageType};
|
||||||
use parking_lot::Once;
|
use parking_lot::Once;
|
||||||
use regex::Regex;
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
static INIT: parking_lot::Once = Once::new();
|
static INIT: parking_lot::Once = Once::new();
|
||||||
|
@ -71,27 +70,26 @@ For future reference, the error summary is as follows:
|
||||||
|
|
||||||
println!("{}", final_msg.red().bold());
|
println!("{}", final_msg.red().bold());
|
||||||
|
|
||||||
if let Err(e) = MessageDialog::new()
|
if let Err(e) = MessageDialog::new()
|
||||||
.set_type(MessageType::Error)
|
.set_type(MessageType::Error)
|
||||||
.set_title("A fatal error in Zenyx has occurred")
|
.set_title("A fatal error in Zenyx has occurred")
|
||||||
.set_text(&final_msg)
|
.set_text(&final_msg)
|
||||||
.show_confirm() {
|
.show_confirm()
|
||||||
error!("Failed to show message dialog: {e}")
|
{
|
||||||
}
|
error!("Failed to show message dialog: {e}")
|
||||||
|
}
|
||||||
Ok(())
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
fn capture_backtrace() -> String {
|
fn capture_backtrace() -> String {
|
||||||
let mut backtrace = String::new();
|
let mut backtrace = String::new();
|
||||||
let sysinfo = crate::metadata::SystemMetadata::current();
|
let sysinfo = crate::metadata::SystemMetadata::current();
|
||||||
backtrace.push_str(&sysinfo.verbose_summary());
|
backtrace.push_str(&sysinfo.verbose_summary());
|
||||||
|
|
||||||
let trace = backtrace::Backtrace::new();
|
let trace = backtrace::Backtrace::new();
|
||||||
let message = format!("\nBacktrace:\n\n");
|
let message = format!("\nBacktrace:\n\n");
|
||||||
backtrace.push_str(&message);
|
backtrace.push_str(&message);
|
||||||
backtrace.push_str(&format!("{trace:?}"));
|
backtrace.push_str(&format!("{trace:?}"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
backtrace
|
backtrace
|
||||||
}
|
}
|
||||||
|
@ -102,8 +100,78 @@ trait Sanitize {
|
||||||
|
|
||||||
impl Sanitize for str {
|
impl Sanitize for str {
|
||||||
fn sanitize_path(&self) -> String {
|
fn sanitize_path(&self) -> String {
|
||||||
let username_pattern = r"(?i)(/home/|/Users/|\\Users\\)([^/\\]+)";
|
let prefixes = ["/home/", "/Users/", "\\Users\\", "/opt/home/"];
|
||||||
let re = Regex::new(username_pattern).expect("Failed to compile regex for sanitization");
|
let mut result = String::from(self);
|
||||||
re.replace_all(self, "${1}<USER>").to_string()
|
|
||||||
|
for prefix in prefixes {
|
||||||
|
if let Some(start_index) = result.find(prefix) {
|
||||||
|
let start_of_user = start_index + prefix.len();
|
||||||
|
let mut end_of_user = result[start_of_user..]
|
||||||
|
.find(|c| c == '/' || c == '\\')
|
||||||
|
.map(|i| start_of_user + i)
|
||||||
|
.unwrap_or(result.len());
|
||||||
|
if end_of_user == start_of_user && start_of_user < result.len() {
|
||||||
|
end_of_user = result.len();
|
||||||
|
}
|
||||||
|
result.replace_range(start_of_user..end_of_user, "<USER>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sanitize_home() {
|
||||||
|
assert_eq!(
|
||||||
|
"/home/<USER>/documents",
|
||||||
|
"/home/john.doe/documents".sanitize_path()
|
||||||
|
);
|
||||||
|
assert_eq!("/home/<USER>", "/home/jane".sanitize_path());
|
||||||
|
assert_eq!("/opt/home/<USER>", "/opt/home/user".sanitize_path());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sanitize_users_unix() {
|
||||||
|
assert_eq!(
|
||||||
|
"/Users/<USER>/desktop",
|
||||||
|
"/Users/alice/desktop".sanitize_path()
|
||||||
|
);
|
||||||
|
assert_eq!("/Users/<USER>/", "/Users/bob/".sanitize_path());
|
||||||
|
assert_eq!("/user/Users/<USER>", "/user/Users/name".sanitize_path());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sanitize_users_windows() {
|
||||||
|
assert_eq!(
|
||||||
|
"\\Users\\<USER>\\documents",
|
||||||
|
"\\Users\\charlie\\documents".sanitize_path()
|
||||||
|
);
|
||||||
|
assert_eq!("\\Users\\<USER>", "\\Users\\david".sanitize_path());
|
||||||
|
assert_eq!(
|
||||||
|
"C:\\Other\\Users\\<USER>",
|
||||||
|
"C:\\Other\\Users\\folder".sanitize_path()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_match() {
|
||||||
|
assert_eq!("/opt/data/file.txt", "/opt/data/file.txt".sanitize_path());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mixed_separators() {
|
||||||
|
assert_eq!(
|
||||||
|
"/home/<USER>\\documents",
|
||||||
|
"/home/eve\\documents".sanitize_path()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"\\Users\\<USER>/desktop",
|
||||||
|
"\\Users\\frank/desktop".sanitize_path()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{fs, path::PathBuf, str::FromStr};
|
use std::{fs, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
use super::{handler::Command, input::tokenize};
|
use super::{handler::Command, input::tokenize};
|
||||||
use crate::core::repl::handler::COMMAND_MANAGER;
|
use crate::core::repl::handler::COMMAND_MANAGER;
|
||||||
|
@ -286,14 +285,7 @@ fn eval(input: String) -> Result<Vec<(String, Option<Vec<String>>)>, ZenyxError>
|
||||||
.with_message("Input was empty")
|
.with_message("Input was empty")
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
let commands: Vec<&str> = input.split(|c| c == ';' || c == '\n').collect();
|
||||||
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![];
|
let mut evaluted = vec![];
|
||||||
|
|
||||||
for command in commands {
|
for command in commands {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::{
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use regex::Regex;
|
|
||||||
use rustyline::{
|
use rustyline::{
|
||||||
Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext, EventHandler, Helper,
|
Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext, EventHandler, Helper,
|
||||||
Hinter, KeyEvent, RepeatCount, Validator, completion::Completer, error::ReadlineError,
|
Hinter, KeyEvent, RepeatCount, Validator, completion::Completer, error::ReadlineError,
|
||||||
|
@ -131,12 +130,10 @@ pub fn tokenize(command: &str) -> Vec<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_command(input: &str) -> Result<Vec<String>> {
|
pub fn parse_command(input: &str) -> Result<Vec<String>> {
|
||||||
let pattern = Regex::new(r"[;|\n]").map_err(|_| {
|
let commands = input
|
||||||
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
|
.split(|c| c == ';' || c == '\n')
|
||||||
.with_message("Failed to compile regex pattern")
|
.map(|slice| slice.to_string())
|
||||||
.build()
|
.collect::<Vec<String>>();
|
||||||
})?;
|
|
||||||
let commands: Vec<String> = pattern.split(input).map(String::from).collect();
|
|
||||||
Ok(commands)
|
Ok(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,12 +142,10 @@ pub fn evaluate_command(input: &str) -> Result<()> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let pattern = Regex::new(r"[;|\n]").map_err(|_| {
|
let commands = input
|
||||||
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
|
.split(|c| c == ';' || c == '\n')
|
||||||
.with_message("Failed to compile regex pattern")
|
.map(|slice| slice.to_string())
|
||||||
.build()
|
.collect::<Vec<String>>();
|
||||||
})?;
|
|
||||||
let commands: Vec<&str> = pattern.split(input).collect();
|
|
||||||
|
|
||||||
for command in commands {
|
for command in commands {
|
||||||
let command = command.trim();
|
let command = command.trim();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue