1use std::slice::{Iter, IterMut};
2use wildmatch::WildMatch;
3
4#[derive(Default, PartialEq, Clone, Debug)]
5pub struct WildMap<T> {
6 exact_items: Vec<(String, T)>,
7 wild_items: Vec<(String, WildMatch, T)>,
8}
9
10impl<T> WildMap<T>
11where
12 T: Clone,
13{
14 pub fn new() -> Self {
15 Self {
16 exact_items: Vec::new(),
17 wild_items: Vec::new(),
18 }
19 }
20 pub fn insert(&mut self, key: String, value: T) {
21 if key.contains("*") {
22 self.wild_items
23 .push((key.clone(), WildMatch::new(key.as_str()), value));
24 } else {
25 self.exact_items.push((key.clone(), value));
26 }
27 }
28 fn get_impl(&self, key: &str) -> Option<(&str, &T)> {
29 for (store_key, v) in &self.exact_items {
30 if store_key == key {
31 return Some((store_key.as_str(), v));
32 }
33 }
34 for (store_key, wild, v) in &self.wild_items {
35 if wild.matches(key) {
36 return Some((store_key.as_str(), v));
37 }
38 }
39 None
40 }
41 pub fn get(&self, key: &str) -> Option<&T> {
42 self.get_impl(key).map(|x| x.1)
43 }
44 pub fn get_more(&self, key: &str) -> Option<(&str, &T)> {
45 self.get_impl(key)
46 }
47 pub fn len(&self) -> usize {
48 self.exact_items.len() + self.wild_items.len()
49 }
50 pub fn is_empty(&self) -> bool {
51 self.exact_items.is_empty() && self.wild_items.is_empty()
52 }
53
54 pub fn exact_iter(&self) -> Iter<'_, (String, T)> {
55 self.exact_items.iter()
56 }
57 pub fn wild_iter(&self) -> Iter<'_, (String, WildMatch, T)> {
58 self.wild_items.iter()
59 }
60 pub fn exact_iter_mut(&mut self) -> IterMut<'_, (String, T)> {
61 self.exact_items.iter_mut()
62 }
63 pub fn wild_iter_mut(&mut self) -> IterMut<'_, (String, WildMatch, T)> {
64 self.wild_items.iter_mut()
65 }
66}