wp-lang 0.3.0

WPL language crate with AST, parser, evaluator, builtins, and generators.
Documentation
use std::slice::{Iter, IterMut};
use wildmatch::WildMatch;

#[derive(Default, PartialEq, Clone, Debug)]
pub struct WildMap<T> {
    exact_items: Vec<(String, T)>,
    wild_items: Vec<(String, WildMatch, T)>,
}

impl<T> WildMap<T>
where
    T: Clone,
{
    pub fn new() -> Self {
        Self {
            exact_items: Vec::new(),
            wild_items: Vec::new(),
        }
    }
    pub fn insert(&mut self, key: String, value: T) {
        if key.contains("*") {
            self.wild_items
                .push((key.clone(), WildMatch::new(key.as_str()), value));
        } else {
            self.exact_items.push((key.clone(), value));
        }
    }
    fn get_impl(&self, key: &str) -> Option<(&str, &T)> {
        for (store_key, v) in &self.exact_items {
            if store_key == key {
                return Some((store_key.as_str(), v));
            }
        }
        for (store_key, wild, v) in &self.wild_items {
            if wild.matches(key) {
                return Some((store_key.as_str(), v));
            }
        }
        None
    }
    pub fn get(&self, key: &str) -> Option<&T> {
        self.get_impl(key).map(|x| x.1)
    }
    pub fn get_more(&self, key: &str) -> Option<(&str, &T)> {
        self.get_impl(key)
    }
    pub fn len(&self) -> usize {
        self.exact_items.len() + self.wild_items.len()
    }
    pub fn is_empty(&self) -> bool {
        self.exact_items.is_empty() && self.wild_items.is_empty()
    }

    pub fn exact_iter(&self) -> Iter<'_, (String, T)> {
        self.exact_items.iter()
    }
    pub fn wild_iter(&self) -> Iter<'_, (String, WildMatch, T)> {
        self.wild_items.iter()
    }
    pub fn exact_iter_mut(&mut self) -> IterMut<'_, (String, T)> {
        self.exact_items.iter_mut()
    }
    pub fn wild_iter_mut(&mut self) -> IterMut<'_, (String, WildMatch, T)> {
        self.wild_items.iter_mut()
    }
}