hara-native 0.1.13

HAL-free native host runtime and package launcher for Hara
Documentation
use std::collections::{HashMap, HashSet, VecDeque};
use std::hash::Hash;

#[derive(Debug, Clone, Default)]
pub struct AsList<E>(VecDeque<E>);
impl<E> AsList<E> {
    pub fn new(values: impl IntoIterator<Item = E>) -> Self {
        Self(values.into_iter().collect())
    }
    pub fn len(&self) -> usize {
        self.0.len()
    }
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
    pub fn empty(&mut self) -> &mut Self {
        self.0.clear();
        self
    }
    pub fn nth(&self, index: usize) -> Option<&E> {
        self.0.get(index)
    }
    pub fn peek_first(&self) -> Option<&E> {
        self.0.front()
    }
    pub fn peek_last(&self) -> Option<&E> {
        self.0.back()
    }
    pub fn pop_first(&mut self) -> Option<E> {
        self.0.pop_front()
    }
    pub fn pop_last(&mut self) -> Option<E> {
        self.0.pop_back()
    }
    pub fn push_first(&mut self, value: E) -> &mut Self {
        self.0.push_front(value);
        self
    }
    pub fn push_last(&mut self, value: E) -> &mut Self {
        self.0.push_back(value);
        self
    }
    pub fn iter(&self) -> impl Iterator<Item = &E> {
        self.0.iter()
    }
}

#[derive(Debug, Clone, Default)]
pub struct AsMap<K, V>(HashMap<K, V>);
impl<K: Eq + Hash, V> AsMap<K, V> {
    pub fn new(values: impl IntoIterator<Item = (K, V)>) -> Self {
        Self(values.into_iter().collect())
    }
    pub fn len(&self) -> usize {
        self.0.len()
    }
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
    pub fn assoc(&mut self, key: K, value: V) -> &mut Self {
        self.0.insert(key, value);
        self
    }
    pub fn dissoc(&mut self, key: &K) -> &mut Self {
        self.0.remove(key);
        self
    }
    pub fn empty(&mut self) -> &mut Self {
        self.0.clear();
        self
    }
    pub fn find(&self, key: &K) -> Option<(&K, &V)> {
        self.0.get_key_value(key)
    }
    pub fn get(&self, key: &K) -> Option<&V> {
        self.0.get(key)
    }
    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
        self.0.iter()
    }
}

#[derive(Debug, Clone, Default)]
pub struct AsSet<E>(HashSet<E>);
impl<E: Eq + Hash> AsSet<E> {
    pub fn new(values: impl IntoIterator<Item = E>) -> Self {
        Self(values.into_iter().collect())
    }
    pub fn len(&self) -> usize {
        self.0.len()
    }
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
    pub fn conj(&mut self, value: E) -> &mut Self {
        self.0.insert(value);
        self
    }
    pub fn dissoc(&mut self, value: &E) -> &mut Self {
        self.0.remove(value);
        self
    }
    pub fn empty(&mut self) -> &mut Self {
        self.0.clear();
        self
    }
    pub fn find(&self, value: &E) -> Option<&E> {
        self.0.get(value)
    }
    pub fn iter(&self) -> impl Iterator<Item = &E> {
        self.0.iter()
    }
}

#[cfg(test)]
mod tests {
    use super::{AsList, AsMap, AsSet};
    #[test]
    fn expose_mutable_host_collections() {
        let mut list = AsList::new([2]);
        list.push_first(1).push_last(3);
        assert_eq!(list.iter().copied().collect::<Vec<_>>(), vec![1, 2, 3]);
        let mut map = AsMap::new([]);
        map.assoc("a", 1);
        assert_eq!(map.get(&"a"), Some(&1));
        let mut set = AsSet::new([1, 1]);
        set.conj(2);
        assert_eq!(set.len(), 2);
    }
}