diff --git a/Cargo.lock b/Cargo.lock index 8d2349a..f4d9019 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,6 +531,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -723,6 +729,7 @@ dependencies = [ "nix", "nu-ansi-term 0.50.0", "once_cell", + "regex-lite", "serde", "serde_json", "subprocess", diff --git a/tokio-bin-process/Cargo.toml b/tokio-bin-process/Cargo.toml index 0a87b12..d73ccb1 100644 --- a/tokio-bin-process/Cargo.toml +++ b/tokio-bin-process/Cargo.toml @@ -21,6 +21,7 @@ itertools = "0.13.0" once_cell = "1.17.1" chrono = "0.4.24" cargo_metadata = "0.18.0" +regex-lite = "0.1.6" [dev-dependencies] -tokio = { version = "1.25.0", features = ["macros", "rt-multi-thread", "time"] } \ No newline at end of file +tokio = { version = "1.25.0", features = ["macros", "rt-multi-thread", "time"] } diff --git a/tokio-bin-process/src/event_matcher.rs b/tokio-bin-process/src/event_matcher.rs index 49ad20c..26434f8 100644 --- a/tokio-bin-process/src/event_matcher.rs +++ b/tokio-bin-process/src/event_matcher.rs @@ -4,6 +4,7 @@ use std::fmt::Display; use crate::event::{Event, Level}; use itertools::Itertools; +use regex_lite::Regex; /// Use to check for any matching [`Event`]'s among a list of events. #[derive(Debug)] @@ -63,6 +64,7 @@ impl Display for Events { pub struct EventMatcher { level: Matcher, message: Matcher, + message_regex: RegexMatcher, target: Matcher, pub(crate) count: Count, } @@ -91,6 +93,12 @@ impl EventMatcher { self } + /// Sets the matcher to only match an [`Event`] when it has the exact provided message + pub fn with_message_regex(mut self, message: &str) -> EventMatcher { + self.message_regex = RegexMatcher::new(message); + self + } + /// Defines how many times the matcher must match to pass an assertion /// /// This is not used internally i.e. it has no effect on [`EventMatcher::matches`] @@ -104,6 +112,7 @@ impl EventMatcher { pub fn matches(&self, event: &Event) -> bool { self.level.matches(&event.level) && self.message.matches(&event.fields.message) + && self.message_regex.matches(&event.fields.message) && self.target.matches(&event.target) } } @@ -145,3 +154,25 @@ impl Matcher { } } } + +#[derive(Debug, Default)] +enum RegexMatcher { + Matches(Regex), + #[default] + Any, +} + +impl RegexMatcher { + fn new(pattern: &str) -> Self { + RegexMatcher::Matches(regex_lite::Regex::new(pattern).unwrap()) + } +} + +impl RegexMatcher { + fn matches(&self, value: &str) -> bool { + match self { + RegexMatcher::Matches(regex) => regex.is_match(value), + RegexMatcher::Any => true, + } + } +}