use std::{borrow::Borrow, collections::HashMap, hash::Hash};
use ahash::RandomState;
use super::Resolver;
use crate::{
prelude::*,
resolver::{Locked, LockedResolver, ResolverState, Unlocked, UnlockedResolver},
};
pub struct DefaultResolver<S, K, V>
where
S: ResolverState,
K: Borrow<str> + PartialEq<String> + Eq + Hash,
{
vars: HashMap<K, V, RandomState>,
_state: S,
}
impl<K, V> LockedResolver<V> for DefaultResolver<Locked, K, V> where
K: Borrow<str> + PartialEq<String> + Eq + Hash
{
}
impl<K, V> UnlockedResolver<V, DefaultResolver<Locked, K, V>> for DefaultResolver<Unlocked, K, V>
where
K: Borrow<str> + PartialEq<String> + Eq + Hash,
{
fn lock(self) -> DefaultResolver<Locked, K, V>
{
DefaultResolver {
vars: self.vars,
_state: Locked,
}
}
}
impl<S, K, V> Resolver<S, V> for DefaultResolver<S, K, V>
where
S: ResolverState,
K: Borrow<str> + PartialEq<String> + Eq + Hash,
{
fn resolve(&self, name: &str) -> Option<&V>
{
self.vars.get(name)
}
}
impl<K, V> DefaultResolver<Unlocked, K, V>
where
K: Borrow<str> + PartialEq<String> + Eq + Hash,
{
pub fn empty() -> Self
{
DefaultResolver {
vars: HashMap::default(),
_state: Unlocked,
}
}
pub fn insert(&mut self, name: K, val: V)
{
self.vars.insert(name, val);
}
}
impl DefaultResolver<Unlocked, String, f64>
{
pub fn new_vars() -> Self
{
let mut hashmap = HashMap::default();
hashmap.insert("pi".to_string(), std::f64::consts::PI);
hashmap.insert("e".to_string(), std::f64::consts::E);
hashmap.insert("tau".to_string(), std::f64::consts::TAU);
hashmap.insert("sqrt2".to_string(), std::f64::consts::SQRT_2);
DefaultResolver {
vars: hashmap,
_state: Unlocked,
}
}
}
impl DefaultResolver<Unlocked, String, ExprFn>
{
pub fn new_fns() -> Self
{
let mut hashmap: HashMap<String, ExprFn, RandomState> = HashMap::default();
hashmap.insert("abs".to_string(), ExprFn(abs));
hashmap.insert("sqrt".to_string(), ExprFn(sqrt));
return DefaultResolver {
vars: hashmap,
_state: Unlocked,
};
}
}
fn abs(x: &[f64]) -> f64
{
x[0].abs()
}
fn sqrt(x: &[f64]) -> f64
{
x[0].sqrt()
}