use std::fmt::{Arguments, Debug, Display};
use pretty_assertions::Comparison;
macro_rules! assert_matches {
($left:expr, $($pattern:pat_param)|+ $(if $guard:expr)? $(,)?) => {
match $left {
$($pattern)|+ $(if $guard)? => {}
ref left => {
crate::tests::assert_matches_failed(
left,
stringify!($($pattern)|+ $(if $guard)?),
None,
);
}
}
};
($left:expr, $($pattern:pat_param)|+ $(if $guard:expr)?, $($arg:tt)+) => {
match $left {
$($pattern)|+ $(if $guard)? => {}
ref left => {
crate::tests::assert_matches_failed(
left,
stringify!($($pattern)|+ $(if $guard)?),
Some(format_args!($($arg)+)),
);
}
}
};
}
pub(crate) use assert_matches;
#[track_caller]
pub(crate) fn assert_matches_failed(left: impl Debug, right: &str, message: Option<Arguments<'_>>) {
struct Pattern<'a>(&'a str);
impl Debug for Pattern<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(self.0, f)
}
}
match message {
Some(message) => panic!(
"{}",
indoc::formatdoc! {"
assertion `left matches right` failed: {message}
{}
",
Comparison::new(&left, &Pattern(right)),
},
),
None => panic!(
"{}",
indoc::formatdoc! {"
assertion `left matches right` failed
{}
",
Comparison::new(&left, &Pattern(right)),
},
),
}
}