coliru

A minimal, flexible, dotfile installer
git clone https://git.ashermorgan.net/coliru/
Log | Files | Refs | README

commit 4f6bc1c3897db4caff16f82512f46cbb7ec877e8
parent 8a021a5d921e2ca96f631ae615842db87ddc1977
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Sun, 16 Jun 2024 21:43:17 -0700

Implement tags_match function

Diffstat:
ACargo.lock | 7+++++++
Asrc/tags.rs | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "coliru" +version = "0.0.0" diff --git a/src/tags.rs b/src/tags.rs @@ -0,0 +1,172 @@ +/// Checks if a set of tags matches a set of rules +/// +/// Rules and tags are both specified as strings. Each rule contains one or more +/// desired tags separated by `|`. A list of tags matches a set of rules if each +/// rule contains at least one tag that appears in the list of tags. The results +/// of rules prefixed with `^` will be negated. An empty list of rules will +/// match any list of tags. +/// +/// ``` +/// let rules = ["linux|macos", "system", "^work"]; +/// let tags_1 = ["macos", "system", "user"]; +/// let tags_2 = ["linux", "system", "work"]; +/// assert_eq!(tags_match(&rules, &tags_1), true); +/// assert_eq!(tags_match(&rules, &tags_2), false); +/// ``` +pub fn tags_match(rules: &[&str], tags: &[&str]) -> bool { + for rule in rules.iter() { + let is_negated = rule.chars().nth(0) == Some('^'); + let _rule: &str; + if is_negated { + _rule = &rule[1..]; // Strip leading '^' + } else { + _rule = &rule; + } + + let tag_found = _rule.split("|").any(|subrule| { + tags.iter().any(|&tag| { + tag == subrule + }) + }); + + if tag_found == is_negated { + return false + } + } + + true +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn tags_match_empty_parameters() { + assert_eq!(tags_match(&[], &[]), true); + assert_eq!(tags_match(&[], &["linux", "user"]), true); + assert_eq!(tags_match(&["linux", "user"], &[]), false); + } + + #[test] + fn tags_match_one_match() { + let tags_1 = ["linux"]; + let tags_2 = ["linux", "windows"]; + + assert_eq!(tags_match(&tags_1.clone(), &tags_1.clone()), true); + assert_eq!(tags_match(&tags_1.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&tags_2.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&tags_2.clone(), &tags_2.clone()), true); + } + + #[test] + fn tags_match_two_matches() { + let tags_1 = ["linux", "user"]; + let tags_2 = ["linux", "user", "windows"]; + + assert_eq!(tags_match(&tags_1.clone(), &tags_1.clone()), true); + assert_eq!(tags_match(&tags_1.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&tags_2.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&tags_2.clone(), &tags_2.clone()), true); + } + + #[test] + fn tags_match_negated() { + let rules = ["^linux"]; + let tags_1 = ["linux"]; + let tags_2 = ["windows"]; + let tags_3 = ["macos"]; + let tags_4 = ["linux", "macos"]; + + assert_eq!(tags_match(&rules.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules.clone(), &tags_4.clone()), false); + } + + #[test] + fn tags_match_negated_two_rules() { + let rules_1 = ["^linux", "^user"]; + let rules_2 = ["^linux", "user"]; + let tags_1 = ["linux", "system"]; + let tags_2 = ["windows", "user"]; + let tags_3 = ["macos", "system"]; + let tags_4 = ["linux", "macos", "user"]; + + assert_eq!(tags_match(&rules_1.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules_1.clone(), &tags_2.clone()), false); + assert_eq!(tags_match(&rules_1.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules_1.clone(), &tags_4.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules_2.clone(), &tags_3.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_4.clone()), false); + } + + #[test] + fn tags_match_union() { + let rules = ["linux|macos"]; + let tags_1 = ["linux"]; + let tags_2 = ["macos"]; + let tags_3 = ["linux", "macos"]; + let tags_4 = ["windows"]; + + assert_eq!(tags_match(&rules.clone(), &tags_1.clone()), true); + assert_eq!(tags_match(&rules.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules.clone(), &tags_4.clone()), false); + } + + #[test] + fn tags_match_union_two_rules() { + let rules_1 = ["linux|macos", "user|system"]; + let rules_2 = ["linux|macos", "user"]; + let tags_1 = ["user", "linux"]; + let tags_2 = ["system", "macos"]; + let tags_3 = ["user", "linux", "macos"]; + let tags_4 = ["system", "windows"]; + + assert_eq!(tags_match(&rules_1.clone(), &tags_1.clone()), true); + assert_eq!(tags_match(&rules_1.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules_1.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules_1.clone(), &tags_4.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_1.clone()), true); + assert_eq!(tags_match(&rules_2.clone(), &tags_2.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules_2.clone(), &tags_4.clone()), false); + } + + #[test] + fn tags_match_union_negated() { + let rules = ["^linux|macos"]; + let tags_1 = ["linux"]; + let tags_2 = ["macos"]; + let tags_3 = ["linux", "macos"]; + let tags_4 = ["windows"]; + + assert_eq!(tags_match(&rules.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules.clone(), &tags_2.clone()), false); + assert_eq!(tags_match(&rules.clone(), &tags_3.clone()), false); + assert_eq!(tags_match(&rules.clone(), &tags_4.clone()), true); + } + + #[test] + fn tags_match_union_negated_two_rules() { + let rules_1 = ["^linux|macos", "^user"]; + let rules_2 = ["^linux|macos", "user|system"]; + let rules_3 = ["^linux|macos", "user"]; + let tags_1 = ["linux", "macos", "system"]; + let tags_2 = ["windows", "user"]; + let tags_3 = ["windows", "system"]; + + assert_eq!(tags_match(&rules_1.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules_1.clone(), &tags_2.clone()), false); + assert_eq!(tags_match(&rules_1.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules_2.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules_2.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules_2.clone(), &tags_3.clone()), true); + assert_eq!(tags_match(&rules_3.clone(), &tags_1.clone()), false); + assert_eq!(tags_match(&rules_3.clone(), &tags_2.clone()), true); + assert_eq!(tags_match(&rules_3.clone(), &tags_3.clone()), false); + } +}