Created
January 28, 2023 01:49
-
-
Save juliusl/dc326001612dfa93f1d770e09f157ee7 to your computer and use it in GitHub Desktop.
Trait to match suffix of types that impl AsRef<str>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mod util { | |
impl<T> MatchSuffix for T where T: AsRef<str> {} | |
/// Trait for checking if self matches a specific suffix, | |
/// | |
pub trait MatchSuffix | |
where | |
Self: AsRef<str>, | |
{ | |
/// Returns true if `pat` is a suffix of self.as_ref::<str>() (.as_ref() implies this type in the rest of this doc), | |
/// | |
/// Caveat: If the length of `pat` is less than .as_ref() this method returns false. | |
/// | |
/// # Wildcard Syntax | |
/// The syntax for `pat` allows for wildcards, i.e. `.value.*`. A wildcard matches any non-whitespace character. | |
/// For example, if self.as_ref() returned "debug.value.test_value", and pat was `.value.*`, this would be considered a match. | |
/// Alternatively, if pat was `de*value.*` this would be considered a match. | |
/// | |
/// Finally, if pat was `prod.value.*`, then it would not be considered a match. | |
/// | |
/// A leading `*` is not required as this function is checking for a suffix match, howvever it is still supported. | |
/// | |
/// To check for `*` in a pat, use `\*` to escape the wildcard symbol. | |
/// | |
/// You can also check for length with wildcards. For example if pat is `*****`, and self.as_ref() is `abc` this would not be considered a match. | |
/// If self.as_ref() was instead `abcde` this would be considered a match. Be careful if using a leading * in this scenario because, in the context of this function a leading * implies that content is expected. | |
/// | |
fn match_suffix(&self, pat: impl AsRef<str>) -> bool { | |
let content = self.as_ref(); | |
if content.len() < pat.as_ref().len() { | |
return false; | |
} | |
let mut previous = 0; | |
let mut is_match = false; | |
let pat = pat.as_ref().replace(r#"\*"#, r#"()"#); | |
let content = content.replace("*", "()"); | |
for part in pat.split("*") { | |
if let Some(pos) = content.find(part) { | |
if part.is_empty() { | |
is_match = content[previous..].len() + previous == content.len(); | |
} else { | |
is_match = pos > previous; | |
previous = pos; | |
} | |
} else { | |
return false; | |
} | |
if !is_match { | |
return false; | |
} | |
} | |
is_match | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment