Rename matches,replace -> regex_{matches,replace}.

Also simplify their error handling.
This commit is contained in:
Quest 2019-04-12 23:03:13 +02:00
parent f6c8689303
commit 7c6b6d4319
5 changed files with 15 additions and 30 deletions

View File

@ -216,8 +216,8 @@ This crate offers a set of builtin functions.
| max | >= 1 | Returns the maximum of the arguments | | max | >= 1 | Returns the maximum of the arguments |
| downcase | 1 | Returns lower-case version of string | | downcase | 1 | Returns lower-case version of string |
| len | 1 | Return the character length of string argument | | len | 1 | Return the character length of string argument |
| match | 2 | Returns true if first string argument matches regex in second | | regex_matches | 2 | Returns true if first string argument matches regex in second |
| replace | 3 | Returns string with matches replaced by third argument | | regex_replace | 3 | Returns string with matches replaced by third argument |
| trim | 1 | Strips whitespace from start and end of string | | trim | 1 | Strips whitespace from start and end of string |
| upcase | 1 | Returns upper-case version of string | | upcase | 1 | Returns upper-case version of string |

View File

@ -84,7 +84,7 @@ impl fmt::Display for EvalexprError {
ModulationError { dividend, divisor } => { ModulationError { dividend, divisor } => {
write!(f, "Error modulating {} % {}", dividend, divisor) write!(f, "Error modulating {} % {}", dividend, divisor)
}, },
InvalidRegex { regex, message } => write!(f, "Regular expression {} is invalid: {}", regex, message), InvalidRegex { regex, message } => write!(f, "Regular expression {:?} is invalid: {:?}", regex, message),
ContextNotManipulable => write!(f, "Cannot manipulate context"), ContextNotManipulable => write!(f, "Cannot manipulate context"),
IllegalEscapeSequence(string) => write!(f, "Illegal escape sequence: {}", string), IllegalEscapeSequence(string) => write!(f, "Illegal escape sequence: {}", string),
CustomMessage(message) => write!(f, "Error: {}", message), CustomMessage(message) => write!(f, "Error: {}", message),

View File

@ -167,7 +167,7 @@ pub enum EvalexprError {
divisor: Value, divisor: Value,
}, },
/// This regular expression could not be parsed /// A regular expression could not be parsed
InvalidRegex { InvalidRegex {
/// The invalid regular expression /// The invalid regular expression
regex: String, regex: String,

View File

@ -7,21 +7,6 @@ use EvalexprError;
use Function; use Function;
use Value; use Value;
#[cfg(feature = "regex_support")]
fn regex_with_local_errors(re_str: &str) -> Result<Regex, EvalexprError> {
match Regex::new(re_str) {
Ok(re) => Ok(re),
Err(regex::Error::Syntax(message)) =>
Err(EvalexprError::invalid_regex(re_str.to_string(), message)),
Err(regex::Error::CompiledTooBig(max_size)) =>
Err(EvalexprError::invalid_regex(
re_str.to_string(),
format!("Regex exceeded max size {}", max_size))
),
Err(err) => Err(EvalexprError::CustomMessage(err.to_string())),
}
}
pub fn builtin_function(identifier: &str) -> Option<Function> { pub fn builtin_function(identifier: &str) -> Option<Function> {
match identifier { match identifier {
"min" => Some(Function::new( "min" => Some(Function::new(
@ -90,27 +75,27 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
}), }),
)), )),
#[cfg(feature = "regex_support")] #[cfg(feature = "regex_support")]
"match" => Some(Function::new( "regex_matches" => Some(Function::new(
Some(2), Some(2),
Box::new(|arguments| { Box::new(|arguments| {
let subject = expect_string(&arguments[0])?; let subject = expect_string(&arguments[0])?;
let re_str = expect_string(&arguments[1])?; let re_str = expect_string(&arguments[1])?;
match regex_with_local_errors(re_str) { match Regex::new(re_str) {
Ok(re) => Ok(Value::Boolean(re.is_match(subject))), Ok(re) => Ok(Value::Boolean(re.is_match(subject))),
Err(err) => Err(err) Err(err) => Err(EvalexprError::invalid_regex(re_str.to_string(), format!("{}", err)))
} }
}), }),
)), )),
#[cfg(feature = "regex_support")] #[cfg(feature = "regex_support")]
"replace" => Some(Function::new( "regex_replace" => Some(Function::new(
Some(3), Some(3),
Box::new(|arguments| { Box::new(|arguments| {
let subject = expect_string(&arguments[0])?; let subject = expect_string(&arguments[0])?;
let re_str = expect_string(&arguments[1])?; let re_str = expect_string(&arguments[1])?;
let repl = expect_string(&arguments[2])?; let repl = expect_string(&arguments[2])?;
match regex_with_local_errors(re_str) { match Regex::new(re_str) {
Ok(re) => Ok(Value::String(re.replace_all(subject, repl).to_string())), Ok(re) => Ok(Value::String(re.replace_all(subject, repl).to_string())),
Err(err) => Err(err), Err(err) => Err(EvalexprError::invalid_regex(re_str.to_string(), format!("{}", err))),
} }
}), }),
)), )),

View File

@ -309,14 +309,14 @@ fn test_builtin_functions() {
#[cfg(feature = "regex_support")] #[cfg(feature = "regex_support")]
fn test_regex_functions() { fn test_regex_functions() {
assert_eq!( assert_eq!(
eval("match(\"foobar\", \"[ob]{3}\")"), eval("regex_matches(\"foobar\", \"[ob]{3}\")"),
Ok(Value::Boolean(true)) Ok(Value::Boolean(true))
); );
assert_eq!( assert_eq!(
eval("match(\"gazonk\", \"[ob]{3}\")"), eval("regex_matches(\"gazonk\", \"[ob]{3}\")"),
Ok(Value::Boolean(false)) Ok(Value::Boolean(false))
); );
match eval("match(\"foo\", \"[\")") { match eval("regex_matches(\"foo\", \"[\")") {
Err(EvalexprError::InvalidRegex{ regex, message }) => { Err(EvalexprError::InvalidRegex{ regex, message }) => {
assert_eq!(regex, "["); assert_eq!(regex, "[");
assert!(message.contains("unclosed character class")); assert!(message.contains("unclosed character class"));
@ -324,11 +324,11 @@ fn test_regex_functions() {
v => panic!(v), v => panic!(v),
}; };
assert_eq!( assert_eq!(
eval("replace(\"foobar\", \".*?(o+)\", \"b$1\")"), eval("regex_replace(\"foobar\", \".*?(o+)\", \"b$1\")"),
Ok(Value::String("boobar".to_owned())) Ok(Value::String("boobar".to_owned()))
); );
assert_eq!( assert_eq!(
eval("replace(\"foobar\", \".*?(i+)\", \"b$1\")"), eval("regex_replace(\"foobar\", \".*?(i+)\", \"b$1\")"),
Ok(Value::String("foobar".to_owned())) Ok(Value::String("foobar".to_owned()))
); );
} }