use alloc::string::String;
use core::fmt;
#[derive(Debug)]
pub enum Pattern {
Literal(alloc::borrow::Cow<'static, str>),
Regex(regex::Regex),
}
impl Pattern {
#[track_caller]
pub fn regex(pattern: impl AsRef<str>) -> Self {
Self::Regex(regex::Regex::new(pattern.as_ref()).expect("invalid regex"))
}
pub fn is_match(&self, input: impl AsRef<str>) -> bool {
match self {
Self::Literal(pattern) => input.as_ref().contains(pattern.as_ref()),
Self::Regex(regex) => regex.is_match(input.as_ref()),
}
}
#[track_caller]
pub fn assert_match(&self, input: impl AsRef<str>) {
let input = input.as_ref();
if !self.is_match(input) {
panic!(
r"expected string was not found in emitted diagnostics:
expected input to {expected}
matched against: `{actual}`
",
expected = self,
actual = input
);
}
}
#[track_caller]
pub fn assert_match_with_context(&self, input: impl AsRef<str>, context: impl AsRef<str>) {
let input = input.as_ref();
let context = context.as_ref();
if !self.is_match(input) {
panic!(
r"expected string was not found in emitted diagnostics:
expected input to {expected}
matched against: `{actual}`
full output: `{context}`
",
expected = self,
actual = input
);
}
}
}
impl fmt::Display for Pattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Literal(lit) => write!(f, "contain `{lit}`"),
Self::Regex(pat) => write!(f, "match regular expression `{}`", pat.as_str()),
}
}
}
impl From<&'static str> for Pattern {
fn from(s: &'static str) -> Self {
Self::Literal(alloc::borrow::Cow::Borrowed(s.trim()))
}
}
impl From<String> for Pattern {
fn from(s: String) -> Self {
Self::Literal(alloc::borrow::Cow::Owned(s))
}
}
impl From<regex::Regex> for Pattern {
fn from(pat: regex::Regex) -> Self {
Self::Regex(pat)
}
}