1pub fn tags_match(item_tags: &[String], filter_tags: &[String]) -> bool {
3 if item_tags.is_empty() && !filter_tags.is_empty() {
4 return false;
5 }
6 for tag in filter_tags {
7 if !item_tags.contains(tag) {
8 return false;
9 }
10 }
11 true
12}
13
14#[cfg(test)]
15mod tests {
16 use super::*;
17
18 #[test]
19 fn test_tags_match_both_empty() {
20 let item_tags: Vec<String> = vec![];
21 let filter_tags: Vec<String> = vec![];
22 assert!(tags_match(&item_tags, &filter_tags));
23 }
24
25 #[test]
26 fn test_tags_match_empty_items_with_filter() {
27 let item_tags: Vec<String> = vec![];
28 let filter_tags = vec!["tag1".to_string()];
29 assert!(!tags_match(&item_tags, &filter_tags));
30 }
31
32 #[test]
33 fn test_tags_match_all_present() {
34 let item_tags = vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()];
35 let filter_tags = vec!["tag1".to_string(), "tag2".to_string()];
36 assert!(tags_match(&item_tags, &filter_tags));
37 }
38
39 #[test]
40 fn test_tags_match_partial_match() {
41 let item_tags = vec!["tag1".to_string(), "tag2".to_string()];
42 let filter_tags = vec!["tag1".to_string(), "tag3".to_string()];
43 assert!(!tags_match(&item_tags, &filter_tags));
44 }
45
46 #[test]
47 fn test_tags_match_subset() {
48 let item_tags = vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()];
49 let filter_tags = vec!["tag2".to_string()];
50 assert!(tags_match(&item_tags, &filter_tags));
51 }
52
53 #[test]
54 fn test_tags_match_empty_filter() {
55 let item_tags = vec!["tag1".to_string(), "tag2".to_string()];
56 let filter_tags: Vec<String> = vec![];
57 assert!(tags_match(&item_tags, &filter_tags));
58 }
59
60 #[test]
61 fn test_tags_match_exact() {
62 let item_tags = vec!["tag1".to_string(), "tag2".to_string()];
63 let filter_tags = vec!["tag1".to_string(), "tag2".to_string()];
64 assert!(tags_match(&item_tags, &filter_tags));
65 }
66}