use crate::query::{RegexFlags, RegexValue};
#[derive(Clone, Debug)]
#[must_use = "RegexBuilder does nothing until .build() is called"]
pub struct RegexBuilder {
pub(crate) pattern: String,
pub(crate) case_insensitive: bool,
pub(crate) multiline: bool,
pub(crate) dot_all: bool,
}
impl RegexBuilder {
pub fn new(pattern: impl Into<String>) -> Self {
Self {
pattern: pattern.into(),
case_insensitive: false,
multiline: false,
dot_all: false,
}
}
pub fn case_insensitive(mut self) -> Self {
self.case_insensitive = true;
self
}
pub fn multiline(mut self) -> Self {
self.multiline = true;
self
}
pub fn dot_all(mut self) -> Self {
self.dot_all = true;
self
}
pub fn build(self) -> Result<RegexValue, regex::Error> {
let mut builder = regex::RegexBuilder::new(&self.pattern);
builder.case_insensitive(self.case_insensitive);
builder.multi_line(self.multiline);
builder.dot_matches_new_line(self.dot_all);
builder.build()?;
Ok(RegexValue {
pattern: self.pattern,
flags: RegexFlags {
case_insensitive: self.case_insensitive,
multiline: self.multiline,
dot_all: self.dot_all,
},
})
}
pub(crate) fn into_regex_value(self) -> RegexValue {
RegexValue {
pattern: self.pattern,
flags: RegexFlags {
case_insensitive: self.case_insensitive,
multiline: self.multiline,
dot_all: self.dot_all,
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_pattern() {
let regex = RegexBuilder::new("test.*").build().unwrap();
assert_eq!(regex.pattern, "test.*");
assert!(!regex.flags.case_insensitive);
assert!(!regex.flags.multiline);
assert!(!regex.flags.dot_all);
}
#[test]
fn test_case_insensitive() {
let regex = RegexBuilder::new("Test")
.case_insensitive()
.build()
.unwrap();
assert!(regex.flags.case_insensitive);
assert!(!regex.flags.multiline);
assert!(!regex.flags.dot_all);
}
#[test]
fn test_multiline() {
let regex = RegexBuilder::new("^fn ").multiline().build().unwrap();
assert!(!regex.flags.case_insensitive);
assert!(regex.flags.multiline);
assert!(!regex.flags.dot_all);
}
#[test]
fn test_dot_all() {
let regex = RegexBuilder::new("fn.*}").dot_all().build().unwrap();
assert!(!regex.flags.case_insensitive);
assert!(!regex.flags.multiline);
assert!(regex.flags.dot_all);
}
#[test]
fn test_multiple_flags() {
let regex = RegexBuilder::new("Test.*")
.case_insensitive()
.multiline()
.dot_all()
.build()
.unwrap();
assert!(regex.flags.case_insensitive);
assert!(regex.flags.multiline);
assert!(regex.flags.dot_all);
}
#[test]
fn test_invalid_pattern() {
let result = RegexBuilder::new("[invalid").build();
assert!(result.is_err());
}
#[test]
fn test_into_regex_value_no_validation() {
let regex = RegexBuilder::new("[invalid").into_regex_value();
assert_eq!(regex.pattern, "[invalid");
}
#[test]
fn test_clone() {
let builder = RegexBuilder::new("test").case_insensitive();
let cloned = builder.clone();
assert_eq!(cloned.pattern, "test");
assert!(cloned.case_insensitive);
}
}