miden_assembly_syntax/testing/
pattern.rs1use alloc::string::String;
2use core::fmt;
3
4#[derive(Debug)]
7pub enum Pattern {
8 Literal(alloc::borrow::Cow<'static, str>),
10 Regex(regex::Regex),
12}
13impl Pattern {
14 #[track_caller]
16 pub fn regex(pattern: impl AsRef<str>) -> Self {
17 Self::Regex(regex::Regex::new(pattern.as_ref()).expect("invalid regex"))
18 }
19
20 pub fn is_match(&self, input: impl AsRef<str>) -> bool {
22 match self {
23 Self::Literal(pattern) => input.as_ref().contains(pattern.as_ref()),
24 Self::Regex(regex) => regex.is_match(input.as_ref()),
25 }
26 }
27
28 #[track_caller]
35 pub fn assert_match(&self, input: impl AsRef<str>) {
36 let input = input.as_ref();
37 if !self.is_match(input) {
38 panic!(
39 r"expected string was not found in emitted diagnostics:
40expected input to {expected}
41matched against: `{actual}`
42",
43 expected = self,
44 actual = input
45 );
46 }
47 }
48
49 #[track_caller]
52 pub fn assert_match_with_context(&self, input: impl AsRef<str>, context: impl AsRef<str>) {
53 let input = input.as_ref();
54 let context = context.as_ref();
55 if !self.is_match(input) {
56 panic!(
57 r"expected string was not found in emitted diagnostics:
58expected input to {expected}
59matched against: `{actual}`
60full output: `{context}`
61",
62 expected = self,
63 actual = input
64 );
65 }
66 }
67}
68
69impl fmt::Display for Pattern {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 match self {
72 Self::Literal(lit) => write!(f, "contain `{lit}`"),
73 Self::Regex(pat) => write!(f, "match regular expression `{}`", pat.as_str()),
74 }
75 }
76}
77
78impl From<&'static str> for Pattern {
79 fn from(s: &'static str) -> Self {
80 Self::Literal(alloc::borrow::Cow::Borrowed(s.trim()))
81 }
82}
83
84impl From<String> for Pattern {
85 fn from(s: String) -> Self {
86 Self::Literal(alloc::borrow::Cow::Owned(s))
87 }
88}
89
90impl From<regex::Regex> for Pattern {
91 fn from(pat: regex::Regex) -> Self {
92 Self::Regex(pat)
93 }
94}