Format code
This commit is contained in:
parent
beab299aa0
commit
2a2fbbd792
|
@ -19,10 +19,7 @@
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Key {
|
Key { key: Key, chars: Option<String> },
|
||||||
key: Key,
|
|
||||||
chars: Option<String>
|
|
||||||
},
|
|
||||||
VirtualSeparator,
|
VirtualSeparator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,4 +78,4 @@ pub enum Key {
|
||||||
|
|
||||||
// Others
|
// Others
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ use std::collections::HashMap;
|
||||||
use log::error;
|
use log::error;
|
||||||
use regex::{Regex, RegexSet};
|
use regex::{Regex, RegexSet};
|
||||||
|
|
||||||
use crate::{MatchResult, event::Event};
|
|
||||||
use crate::Matcher;
|
use crate::Matcher;
|
||||||
|
use crate::{event::Event, MatchResult};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RegexMatch<Id> {
|
pub struct RegexMatch<Id> {
|
||||||
|
@ -92,7 +92,6 @@ where
|
||||||
if let Some(captures) = regex.captures(&buffer) {
|
if let Some(captures) = regex.captures(&buffer) {
|
||||||
let full_match = captures.get(0).map_or("", |m| m.as_str());
|
let full_match = captures.get(0).map_or("", |m| m.as_str());
|
||||||
if !full_match.is_empty() {
|
if !full_match.is_empty() {
|
||||||
|
|
||||||
// Now extract the captured names as variables
|
// Now extract the captured names as variables
|
||||||
let variables: HashMap<String, String> = regex
|
let variables: HashMap<String, String> = regex
|
||||||
.capture_names()
|
.capture_names()
|
||||||
|
@ -110,12 +109,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("received inconsistent index from regex set with index: {}", index);
|
error!(
|
||||||
|
"received inconsistent index from regex set with index: {}",
|
||||||
|
index
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matches.is_empty() {
|
if !matches.is_empty() {
|
||||||
return (RegexMatcherState::default(), matches)
|
return (RegexMatcherState::default(), matches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +146,12 @@ impl<Id: Clone> RegexMatcher<Id> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let regex_set = RegexSet::new(&good_regexes).expect("unable to build regex set");
|
let regex_set = RegexSet::new(&good_regexes).expect("unable to build regex set");
|
||||||
|
|
||||||
Self { ids, regex_set, regexes }
|
Self {
|
||||||
|
ids,
|
||||||
|
regex_set,
|
||||||
|
regexes,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,9 +161,10 @@ mod tests {
|
||||||
use crate::util::tests::get_matches_after_str;
|
use crate::util::tests::get_matches_after_str;
|
||||||
|
|
||||||
fn match_result<Id: Default>(id: Id, trigger: &str, vars: &[(&str, &str)]) -> MatchResult<Id> {
|
fn match_result<Id: Default>(id: Id, trigger: &str, vars: &[(&str, &str)]) -> MatchResult<Id> {
|
||||||
let vars: HashMap<String, String> = vars.iter().map(|(key, value)| {
|
let vars: HashMap<String, String> = vars
|
||||||
(key.to_string(), value.to_string())
|
.iter()
|
||||||
}).collect();
|
.map(|(key, value)| (key.to_string(), value.to_string()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
MatchResult {
|
MatchResult {
|
||||||
id,
|
id,
|
||||||
|
@ -173,10 +180,22 @@ mod tests {
|
||||||
RegexMatch::new(2, "num\\d{1,3}s"),
|
RegexMatch::new(2, "num\\d{1,3}s"),
|
||||||
]);
|
]);
|
||||||
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
||||||
assert_eq!(get_matches_after_str("hello", &matcher), vec![match_result(1, "hello", &[])]);
|
assert_eq!(
|
||||||
assert_eq!(get_matches_after_str("say hello", &matcher), vec![match_result(1, "hello", &[])]);
|
get_matches_after_str("hello", &matcher),
|
||||||
assert_eq!(get_matches_after_str("num1s", &matcher), vec![match_result(2, "num1s", &[])]);
|
vec![match_result(1, "hello", &[])]
|
||||||
assert_eq!(get_matches_after_str("num134s", &matcher), vec![match_result(2, "num134s", &[])]);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("say hello", &matcher),
|
||||||
|
vec![match_result(1, "hello", &[])]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("num1s", &matcher),
|
||||||
|
vec![match_result(2, "num1s", &[])]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("num134s", &matcher),
|
||||||
|
vec![match_result(2, "num134s", &[])]
|
||||||
|
);
|
||||||
assert_eq!(get_matches_after_str("nums", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("nums", &matcher), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +206,18 @@ mod tests {
|
||||||
RegexMatch::new(2, "multi\\((?P<name1>.*?),(?P<name2>.*?)\\)"),
|
RegexMatch::new(2, "multi\\((?P<name1>.*?),(?P<name2>.*?)\\)"),
|
||||||
]);
|
]);
|
||||||
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
||||||
assert_eq!(get_matches_after_str("say hello(mary)", &matcher), vec![match_result(1, "hello(mary)", &[("name", "mary")])]);
|
assert_eq!(
|
||||||
|
get_matches_after_str("say hello(mary)", &matcher),
|
||||||
|
vec![match_result(1, "hello(mary)", &[("name", "mary")])]
|
||||||
|
);
|
||||||
assert_eq!(get_matches_after_str("hello(mary", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("hello(mary", &matcher), vec![]);
|
||||||
assert_eq!(get_matches_after_str("multi(mary,jane)", &matcher), vec![match_result(2, "multi(mary,jane)", &[("name1", "mary"), ("name2", "jane")])]);
|
assert_eq!(
|
||||||
|
get_matches_after_str("multi(mary,jane)", &matcher),
|
||||||
|
vec![match_result(
|
||||||
|
2,
|
||||||
|
"multi(mary,jane)",
|
||||||
|
&[("name1", "mary"), ("name2", "jane")]
|
||||||
|
)]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,16 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::{RollingMatch, tree::{MatcherTreeNode, MatcherTreeRef}, util::extract_string_from_events};
|
use super::{
|
||||||
use crate::{MatchResult, event::{Event, Key}};
|
tree::{MatcherTreeNode, MatcherTreeRef},
|
||||||
|
util::extract_string_from_events,
|
||||||
|
RollingMatch,
|
||||||
|
};
|
||||||
use crate::Matcher;
|
use crate::Matcher;
|
||||||
|
use crate::{
|
||||||
|
event::{Event, Key},
|
||||||
|
MatchResult,
|
||||||
|
};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -76,19 +83,26 @@ where
|
||||||
// First compute the old refs
|
// First compute the old refs
|
||||||
if let Some(prev_state) = prev_state {
|
if let Some(prev_state) = prev_state {
|
||||||
for node_path in prev_state.paths.iter() {
|
for node_path in prev_state.paths.iter() {
|
||||||
next_refs.extend(self.find_refs(node_path.node, &event).into_iter().map(|node_ref| {
|
next_refs.extend(
|
||||||
let mut new_events = node_path.events.clone();
|
self
|
||||||
new_events.push(event.clone());
|
.find_refs(node_path.node, &event)
|
||||||
(node_ref, new_events)
|
.into_iter()
|
||||||
}));
|
.map(|node_ref| {
|
||||||
|
let mut new_events = node_path.events.clone();
|
||||||
|
new_events.push(event.clone());
|
||||||
|
(node_ref, new_events)
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate new ones
|
// Calculate new ones
|
||||||
let root_refs = self.find_refs(&self.root, &event);
|
let root_refs = self.find_refs(&self.root, &event);
|
||||||
next_refs.extend(root_refs.into_iter().map(|node_ref| {
|
next_refs.extend(
|
||||||
(node_ref, vec![event.clone()])
|
root_refs
|
||||||
}));
|
.into_iter()
|
||||||
|
.map(|node_ref| (node_ref, vec![event.clone()])),
|
||||||
|
);
|
||||||
|
|
||||||
let mut next_paths = Vec::new();
|
let mut next_paths = Vec::new();
|
||||||
|
|
||||||
|
@ -96,13 +110,14 @@ where
|
||||||
match node_ref {
|
match node_ref {
|
||||||
MatcherTreeRef::Matches(matches) => {
|
MatcherTreeRef::Matches(matches) => {
|
||||||
let trigger = extract_string_from_events(&events);
|
let trigger = extract_string_from_events(&events);
|
||||||
let results = matches.iter().map(|id| {
|
let results = matches
|
||||||
MatchResult {
|
.iter()
|
||||||
id: id.clone(),
|
.map(|id| MatchResult {
|
||||||
trigger: trigger.clone(),
|
id: id.clone(),
|
||||||
|
trigger: trigger.clone(),
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
}
|
})
|
||||||
}).collect();
|
.collect();
|
||||||
|
|
||||||
// Reset the state and return the matches
|
// Reset the state and return the matches
|
||||||
return (RollingMatcherState::default(), results);
|
return (RollingMatcherState::default(), results);
|
||||||
|
@ -191,7 +206,7 @@ impl<Id: Clone> RollingMatcher<Id> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::rolling::{StringMatchOptions};
|
use crate::rolling::StringMatchOptions;
|
||||||
use crate::util::tests::get_matches_after_str;
|
use crate::util::tests::get_matches_after_str;
|
||||||
|
|
||||||
fn match_result<Id: Default>(id: Id, trigger: &str) -> MatchResult<Id> {
|
fn match_result<Id: Default>(id: Id, trigger: &str) -> MatchResult<Id> {
|
||||||
|
@ -217,9 +232,18 @@ mod tests {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(get_matches_after_str("hi", &matcher), vec![match_result(1, "hi"), match_result(5, "hi")]);
|
assert_eq!(
|
||||||
assert_eq!(get_matches_after_str("my", &matcher), vec![match_result(3, "my")]);
|
get_matches_after_str("hi", &matcher),
|
||||||
assert_eq!(get_matches_after_str("mmy", &matcher), vec![match_result(3, "my")]);
|
vec![match_result(1, "hi"), match_result(5, "hi")]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("my", &matcher),
|
||||||
|
vec![match_result(3, "my")]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("mmy", &matcher),
|
||||||
|
vec![match_result(3, "my")]
|
||||||
|
);
|
||||||
assert_eq!(get_matches_after_str("invalid", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("invalid", &matcher), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +269,10 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("hi", &matcher), vec![]);
|
||||||
assert_eq!(get_matches_after_str(".hi,", &matcher), vec![match_result(1, ".hi,")]);
|
assert_eq!(
|
||||||
|
get_matches_after_str(".hi,", &matcher),
|
||||||
|
vec![match_result(1, ".hi,")]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -277,11 +304,26 @@ mod tests {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(get_matches_after_str("hi", &matcher), vec![match_result(1, "hi")]);
|
assert_eq!(
|
||||||
assert_eq!(get_matches_after_str("Hi", &matcher), vec![match_result(1, "Hi")]);
|
get_matches_after_str("hi", &matcher),
|
||||||
assert_eq!(get_matches_after_str("HI", &matcher), vec![match_result(1, "HI")]);
|
vec![match_result(1, "hi")]
|
||||||
assert_eq!(get_matches_after_str("arty", &matcher), vec![match_result(3, "arty")]);
|
);
|
||||||
assert_eq!(get_matches_after_str("arTY", &matcher), vec![match_result(3, "arTY")]);
|
assert_eq!(
|
||||||
|
get_matches_after_str("Hi", &matcher),
|
||||||
|
vec![match_result(1, "Hi")]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("HI", &matcher),
|
||||||
|
vec![match_result(1, "HI")]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("arty", &matcher),
|
||||||
|
vec![match_result(3, "arty")]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_matches_after_str("arTY", &matcher),
|
||||||
|
vec![match_result(3, "arTY")]
|
||||||
|
);
|
||||||
assert_eq!(get_matches_after_str("ARTY", &matcher), vec![]);
|
assert_eq!(get_matches_after_str("ARTY", &matcher), vec![]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,10 +119,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match_from_string_left_word() {
|
fn test_match_from_string_left_word() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RollingMatch::from_string(1, "test", &StringMatchOptions {
|
RollingMatch::from_string(
|
||||||
left_word: true,
|
1,
|
||||||
..Default::default()
|
"test",
|
||||||
}),
|
&StringMatchOptions {
|
||||||
|
left_word: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
),
|
||||||
RollingMatch {
|
RollingMatch {
|
||||||
id: 1,
|
id: 1,
|
||||||
items: vec![
|
items: vec![
|
||||||
|
@ -139,10 +143,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match_from_string_right_word() {
|
fn test_match_from_string_right_word() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RollingMatch::from_string(1, "test", &StringMatchOptions {
|
RollingMatch::from_string(
|
||||||
right_word: true,
|
1,
|
||||||
..Default::default()
|
"test",
|
||||||
}),
|
&StringMatchOptions {
|
||||||
|
right_word: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
),
|
||||||
RollingMatch {
|
RollingMatch {
|
||||||
id: 1,
|
id: 1,
|
||||||
items: vec![
|
items: vec![
|
||||||
|
@ -159,10 +167,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match_from_string_case_insensitive() {
|
fn test_match_from_string_case_insensitive() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RollingMatch::from_string(1, "test", &StringMatchOptions {
|
RollingMatch::from_string(
|
||||||
case_insensitive: true,
|
1,
|
||||||
..Default::default()
|
"test",
|
||||||
}),
|
&StringMatchOptions {
|
||||||
|
case_insensitive: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
),
|
||||||
RollingMatch {
|
RollingMatch {
|
||||||
id: 1,
|
id: 1,
|
||||||
items: vec![
|
items: vec![
|
||||||
|
@ -178,11 +190,15 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match_from_string_preserve_case_markers() {
|
fn test_match_from_string_preserve_case_markers() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RollingMatch::from_string(1, "test", &StringMatchOptions {
|
RollingMatch::from_string(
|
||||||
case_insensitive: true,
|
1,
|
||||||
preserve_case_markers: true,
|
"test",
|
||||||
..Default::default()
|
&StringMatchOptions {
|
||||||
}),
|
case_insensitive: true,
|
||||||
|
preserve_case_markers: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
),
|
||||||
RollingMatch {
|
RollingMatch {
|
||||||
id: 1,
|
id: 1,
|
||||||
items: vec![
|
items: vec![
|
||||||
|
|
|
@ -41,33 +41,84 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_string_from_events_all_chars() {
|
fn extract_string_from_events_all_chars() {
|
||||||
assert_eq!(extract_string_from_events(&[
|
assert_eq!(
|
||||||
Event::Key { key: Key::Other, chars: Some("h".to_string()) },
|
extract_string_from_events(&[
|
||||||
Event::Key { key: Key::Other, chars: Some("e".to_string()) },
|
Event::Key {
|
||||||
Event::Key { key: Key::Other, chars: Some("l".to_string()) },
|
key: Key::Other,
|
||||||
Event::Key { key: Key::Other, chars: Some("l".to_string()) },
|
chars: Some("h".to_string())
|
||||||
Event::Key { key: Key::Other, chars: Some("o".to_string()) },
|
},
|
||||||
]), "hello");
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("e".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("l".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("l".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("o".to_string())
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
"hello"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_string_from_events_no_chars() {
|
fn extract_string_from_events_no_chars() {
|
||||||
assert_eq!(extract_string_from_events(&[
|
assert_eq!(
|
||||||
Event::Key { key: Key::ArrowUp, chars: None },
|
extract_string_from_events(&[
|
||||||
Event::Key { key: Key::ArrowUp, chars: None },
|
Event::Key {
|
||||||
Event::Key { key: Key::ArrowUp, chars: None },
|
key: Key::ArrowUp,
|
||||||
]), "");
|
chars: None
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::ArrowUp,
|
||||||
|
chars: None
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::ArrowUp,
|
||||||
|
chars: None
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_string_from_events_mixed() {
|
fn extract_string_from_events_mixed() {
|
||||||
assert_eq!(extract_string_from_events(&[
|
assert_eq!(
|
||||||
Event::Key { key: Key::Other, chars: Some("h".to_string()) },
|
extract_string_from_events(&[
|
||||||
Event::Key { key: Key::Other, chars: Some("e".to_string()) },
|
Event::Key {
|
||||||
Event::Key { key: Key::Other, chars: Some("l".to_string()) },
|
key: Key::Other,
|
||||||
Event::Key { key: Key::Other, chars: Some("l".to_string()) },
|
chars: Some("h".to_string())
|
||||||
Event::Key { key: Key::Other, chars: Some("o".to_string()) },
|
},
|
||||||
Event::Key { key: Key::ArrowUp, chars: None },
|
Event::Key {
|
||||||
]), "hello");
|
key: Key::Other,
|
||||||
|
chars: Some("e".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("l".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("l".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::Other,
|
||||||
|
chars: Some("o".to_string())
|
||||||
|
},
|
||||||
|
Event::Key {
|
||||||
|
key: Key::ArrowUp,
|
||||||
|
chars: None
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
"hello"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,15 @@
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use crate::{MatchResult, Matcher, event::{Event, Key}};
|
use crate::{
|
||||||
|
event::{Event, Key},
|
||||||
|
MatchResult, Matcher,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn get_matches_after_str<'a, Id: Clone, S, M: Matcher<'a, S, Id>>(string: &str, matcher: &'a M) -> Vec<MatchResult<Id>> {
|
pub(crate) fn get_matches_after_str<'a, Id: Clone, S, M: Matcher<'a, S, Id>>(
|
||||||
|
string: &str,
|
||||||
|
matcher: &'a M,
|
||||||
|
) -> Vec<MatchResult<Id>> {
|
||||||
let mut prev_state = None;
|
let mut prev_state = None;
|
||||||
let mut matches = Vec::new();
|
let mut matches = Vec::new();
|
||||||
|
|
||||||
|
@ -40,4 +46,4 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
matches
|
matches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user