From ab2678082ea488cf50ee375b088c8d357e20226b Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 28 Apr 2026 21:09:41 +0800 Subject: [PATCH] builtin string: add names to RegexError enum fields --- src/builtins/string.rs | 28 ++++++++++++++++++---------- src/builtins/string/match.rs | 7 +++++-- src/builtins/string/replace.rs | 12 +++++++++--- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/builtins/string.rs b/src/builtins/string.rs index 0f2d5b981..d804b0371 100644 --- a/src/builtins/string.rs +++ b/src/builtins/string.rs @@ -152,9 +152,16 @@ enum StringError<'a> { } enum RegexError { - Compile(WString, pcre2::Error), - InvalidCaptureGroupName(WString), - InvalidEscape(WString), + Compile { + pattern: WString, + error: pcre2::Error, + }, + InvalidCaptureGroupName { + name: WString, + }, + InvalidEscape { + replacement: WString, + }, } impl RegexError { @@ -163,14 +170,15 @@ fn print_error(&self, args: &[&wstr], streams: &mut IoStreams) { let subcmd = args[0]; use RegexError::*; match self { - Compile(pattern, e) => { + Compile { pattern, error } => { // TODO: This is misaligned if `pattern` contains characters which are not exactly 1 // terminal cell wide. - let mut marker: WString = - " ".repeat(e.offset().unwrap_or(0).saturating_sub(1)).into(); + let mut marker: WString = " " + .repeat(error.offset().unwrap_or(0).saturating_sub(1)) + .into(); marker.push('^'); - err_fmt!(Error::REGEX_COMPILE, e.error_message()) + err_fmt!(Error::REGEX_COMPILE, error.error_message()) .append_to_msg('\n') .append_to_msg(&err_raw!(pattern).subcmd(cmd, subcmd).to_string()) .append_to_msg('\n') @@ -178,15 +186,15 @@ fn print_error(&self, args: &[&wstr], streams: &mut IoStreams) { .subcmd(cmd, subcmd) .finish(streams); } - InvalidCaptureGroupName(name) => { + InvalidCaptureGroupName { name } => { err_fmt!( "Modification of read-only variable \"%s\" is not allowed", name ) .finish(streams); } - InvalidEscape(pattern) => { - err_fmt!("Invalid escape sequence in pattern \"%s\"", pattern) + InvalidEscape { replacement } => { + err_fmt!("Invalid escape sequence in pattern \"%s\"", replacement) .subcmd(cmd, subcmd) .finish(streams); } diff --git a/src/builtins/string/match.rs b/src/builtins/string/match.rs index 405cc0a32..e04826ed8 100644 --- a/src/builtins/string/match.rs +++ b/src/builtins/string/match.rs @@ -234,7 +234,10 @@ fn new( // the capture group names are valid variable names .block_utf_pattern_directive(true) .build(pattern.as_char_slice()) - .map_err(|e| RegexError::Compile(pattern.to_owned(), e))?; + .map_err(|error| RegexError::Compile { + pattern: pattern.to_owned(), + error, + })?; Self::validate_capture_group_names(regex.capture_names())?; @@ -315,7 +318,7 @@ fn validate_capture_group_names( for name in capture_group_names.iter().filter_map(|n| n.as_ref()) { let wname = str2wcstring(name); if EnvVar::flags_for(&wname).contains(EnvVarFlags::READ_ONLY) { - return Err(RegexError::InvalidCaptureGroupName(wname)); + return Err(RegexError::InvalidCaptureGroupName { name: wname }); } } Ok(()) diff --git a/src/builtins/string/replace.rs b/src/builtins/string/replace.rs index fbaabb2f2..2a79d2774 100644 --- a/src/builtins/string/replace.rs +++ b/src/builtins/string/replace.rs @@ -183,13 +183,19 @@ fn new( // allowed to be user-controlled here .block_utf_pattern_directive(true) .build(pattern.as_char_slice()) - .map_err(|e| RegexError::Compile(pattern.to_owned(), e))?; + .map_err(|error| RegexError::Compile { + pattern: pattern.to_owned(), + error, + })?; let replacement = if feature_test(FeatureFlag::StringReplaceBackslash) { replacement.to_owned() } else { - Self::interpret_escape(replacement) - .ok_or_else(|| RegexError::InvalidEscape(replacement.to_owned()))? + Self::interpret_escape(replacement).ok_or_else(|| { + RegexError::InvalidEscape { + replacement: replacement.to_owned(), + } + })? }; Self::Regex { replacement,