From ea105e48a70512dc45e300f7088280b07a9fa61e Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:23:33 -0600 Subject: [PATCH] replace regex crate with fancy_regex --- Cargo.lock | 3 +- Cargo.toml | 3 +- crates/nu-command/Cargo.toml | 1 - .../nu-command/src/conversions/into/value.rs | 244 ++++++++++-------- crates/nu-command/src/help/help_.rs | 4 +- crates/nu-command/src/strings/split/column.rs | 7 +- crates/nu-command/src/strings/split/list.rs | 5 +- crates/nu-command/src/strings/split/row.rs | 33 ++- tests/eval/mod.rs | 6 +- 9 files changed, 181 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2170445a6..9f5d3d6497 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3160,6 +3160,7 @@ dependencies = [ "crossterm 0.28.1", "ctrlc", "dirs", + "fancy-regex", "log", "miette", "mimalloc", @@ -3187,7 +3188,6 @@ dependencies = [ "openssl", "pretty_assertions", "reedline", - "regex", "rstest", "serde_json", "serial_test", @@ -3387,7 +3387,6 @@ dependencies = [ "rand", "rand_chacha", "rayon", - "regex", "rmp", "roxmltree", "rstest", diff --git a/Cargo.toml b/Cargo.toml index 97bc58c0bd..54f54f4204 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,7 +139,6 @@ rand_chacha = "0.3.1" ratatui = "0.26" rayon = "1.10" reedline = "0.37.0" -regex = "1.9.5" rmp = "0.8" rmp-serde = "1.3" ropey = "1.6.1" @@ -244,7 +243,7 @@ assert_cmd = "2.0" dirs = { workspace = true } tango-bench = "0.6" pretty_assertions = { workspace = true } -regex = { workspace = true } +fancy-regex = { workspace = true } rstest = { workspace = true, default-features = false } serial_test = "3.2" tempfile = { workspace = true } diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index ef88aa92e4..312783faea 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -76,7 +76,6 @@ quick-xml = { workspace = true } rand = { workspace = true, optional = true } getrandom = { workspace = true, optional = true } rayon = { workspace = true } -regex = { workspace = true } roxmltree = { workspace = true } rusqlite = { workspace = true, features = ["bundled", "backup", "chrono"], optional = true } rmp = { workspace = true } diff --git a/crates/nu-command/src/conversions/into/value.rs b/crates/nu-command/src/conversions/into/value.rs index 2d5ae3b17d..de371e27b9 100644 --- a/crates/nu-command/src/conversions/into/value.rs +++ b/crates/nu-command/src/conversions/into/value.rs @@ -1,7 +1,7 @@ use crate::parse_date_from_string; +use fancy_regex::{Regex, RegexBuilder}; use nu_engine::command_prelude::*; use nu_protocol::PipelineIterator; -use regex::{Regex, RegexBuilder}; use std::collections::HashSet; use std::sync::LazyLock; @@ -143,7 +143,7 @@ fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result() .map_err(|_| ShellError::CantConvert { @@ -156,12 +156,12 @@ fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result() .map_err(|_| ShellError::CantConvert { - to_type: "string".to_string(), - from_type: "float".to_string(), + to_type: "float".to_string(), + from_type: "string".to_string(), span, help: Some(format!( r#""{val_str}" does not represent a valid floating point value"# @@ -169,12 +169,12 @@ fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result() .map_err(|_| ShellError::CantConvert { - to_type: "string".to_string(), - from_type: "int".to_string(), + to_type: "int".to_string(), + from_type: "string".to_string(), span, help: Some(format!( r#""{val_str}" does not represent a valid integer value"# @@ -186,15 +186,15 @@ fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result() .map_err(|_| ShellError::CantConvert { - to_type: "string".to_string(), - from_type: "int".to_string(), + to_type: "int".to_string(), + from_type: "string".to_string(), span, help: Some(format!( r#""{val_str}" does not represent a valid integer value"# @@ -206,7 +206,7 @@ fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result Result Result Result { - let escaped_needle = regex::escape(needle); + let escaped_needle = escape(needle); let regex_string = format!("(?i){escaped_needle}"); let regex = match Regex::new(®ex_string) { Ok(regex) => regex, diff --git a/crates/nu-command/src/strings/split/column.rs b/crates/nu-command/src/strings/split/column.rs index 3ed56a56ae..3f355a43c0 100644 --- a/crates/nu-command/src/strings/split/column.rs +++ b/crates/nu-command/src/strings/split/column.rs @@ -1,7 +1,6 @@ +use fancy_regex::{escape, Regex}; use nu_engine::command_prelude::*; -use regex::Regex; - #[derive(Clone)] pub struct SubCommand; @@ -182,7 +181,7 @@ fn split_column( let regex = if args.has_regex { Regex::new(&args.separator.item) } else { - let escaped = regex::escape(&args.separator.item); + let escaped = escape(&args.separator.item); Regex::new(&escaped) } .map_err(|e| ShellError::GenericError { @@ -220,10 +219,12 @@ fn split_column_helper( let split_result: Vec<_> = match max_split { Some(max_split) => separator .splitn(&s, max_split) + .filter_map(|x| x.ok()) .filter(|x| !(collapse_empty && x.is_empty())) .collect(), None => separator .split(&s) + .filter_map(|x| x.ok()) .filter(|x| !(collapse_empty && x.is_empty())) .collect(), }; diff --git a/crates/nu-command/src/strings/split/list.rs b/crates/nu-command/src/strings/split/list.rs index 82f7ec730a..d960b9a515 100644 --- a/crates/nu-command/src/strings/split/list.rs +++ b/crates/nu-command/src/strings/split/list.rs @@ -1,7 +1,6 @@ +use fancy_regex::Regex; use nu_engine::command_prelude::*; -use regex::Regex; - #[derive(Clone)] pub struct SubCommand; @@ -193,7 +192,7 @@ impl Matcher { Ok(match self { Matcher::Regex(regex) => { if let Ok(rhs_str) = rhs.coerce_str() { - regex.is_match(&rhs_str) + regex.is_match(&rhs_str).unwrap_or(false) } else { false } diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index 73da7e6de8..939ac1cc7f 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -1,7 +1,6 @@ +use fancy_regex::{escape, Regex}; use nu_engine::command_prelude::*; -use regex::Regex; - #[derive(Clone)] pub struct SubCommand; @@ -158,7 +157,7 @@ fn split_row( let regex = if args.has_regex { Regex::new(&args.separator.item) } else { - let escaped = regex::escape(&args.separator.item); + let escaped = escape(&args.separator.item); Regex::new(&escaped) } .map_err(|e| ShellError::GenericError { @@ -187,11 +186,35 @@ fn split_row_helper(v: &Value, regex: &Regex, max_split: Option, name: Sp match max_split { Some(max_split) => regex .splitn(&s, max_split) - .map(|x: &str| Value::string(x, v_span)) + .map(|x| match x { + Ok(val) => Value::string(val, v_span), + Err(err) => Value::error( + ShellError::GenericError { + error: "Error with regular expression".into(), + msg: err.to_string(), + span: Some(v_span), + help: None, + inner: vec![], + }, + v_span, + ), + }) .collect(), None => regex .split(&s) - .map(|x: &str| Value::string(x, v_span)) + .map(|x| match x { + Ok(val) => Value::string(val, v_span), + Err(err) => Value::error( + ShellError::GenericError { + error: "Error with regular expression".into(), + msg: err.to_string(), + span: Some(v_span), + help: None, + inner: vec![], + }, + v_span, + ), + }) .collect(), } } else { diff --git a/tests/eval/mod.rs b/tests/eval/mod.rs index b7ad76d32d..c84cdaa873 100644 --- a/tests/eval/mod.rs +++ b/tests/eval/mod.rs @@ -1,5 +1,5 @@ +use fancy_regex::Regex; use nu_test_support::{nu, playground::Playground}; -use regex::Regex; #[test] fn record_with_redefined_key() { @@ -45,7 +45,7 @@ fn test_eval(source: &str, expected_out: ExpectedOut) { Matches(regex) => { let compiled_regex = Regex::new(regex).expect("regex failed to compile"); assert!( - compiled_regex.is_match(&actual.out), + compiled_regex.is_match(&actual.out).unwrap_or(false), "eval out does not match: {}\n{}", regex, actual.out, @@ -55,7 +55,7 @@ fn test_eval(source: &str, expected_out: ExpectedOut) { Error(regex) => { let compiled_regex = Regex::new(regex).expect("regex failed to compile"); assert!( - compiled_regex.is_match(&actual.err), + compiled_regex.is_match(&actual.err).unwrap_or(false), "eval err does not match: {}", regex );