use std::fmt::{self, Display};
use fancy_regex::Regex;
use gazebo::any::AnyLifetime;
use crate as starlark;
use crate::{
environment::{Methods, MethodsBuilder, MethodsStatic},
values::StarlarkValue,
};
#[derive(AnyLifetime, Debug, NoSerialize)]
pub struct StarlarkRegex(pub Regex);
impl StarlarkValue<'_> for StarlarkRegex {
starlark_type!("regex");
fn get_methods(&self) -> Option<&'static Methods> {
static RES: MethodsStatic = MethodsStatic::new();
RES.methods(regex_type_methods)
}
}
impl Display for StarlarkRegex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "regex({:?})", &self.0.as_str())
}
}
starlark_simple_value!(StarlarkRegex);
impl StarlarkRegex {
pub fn new(x: &str) -> anyhow::Result<Self> {
Ok(Self(Regex::new(x)?))
}
}
#[starlark_module]
fn regex_type_methods(builder: &mut MethodsBuilder) {
fn r#match(this: &StarlarkRegex, ref str: &str) -> anyhow::Result<bool> {
Ok(this.0.is_match(str)?)
}
}
#[cfg(test)]
mod tests {
use crate::assert;
#[test]
fn test_match() {
assert::all_true(
r#"
regex("abc|def|ghi").match("abc")
not regex("abc|def|ghi").match("xyz")
not regex("^((?!abc).)*$").match("abc")
regex("^((?!abc).)*$").match("xyz")
"#,
);
}
#[test]
fn test_str() {
assert::is_true(
r#"
str(regex("foo")) == 'regex("foo")'
"#,
);
}
}