kaon 0.1.4

A little scripting language written in rust
Documentation
use std::rc::Rc;

use smallvec::SmallVec;

use crate::Value;

use super::{value::{ToValue, RegisterFunction}, NativeFun, FromValue};

#[derive(Debug, Default)]
pub struct State {
    pub values: SmallVec<[Value; 8]>,
    pub names: SmallVec<[Box<str>; 8]>,
}

impl State {
    pub fn new() -> Self {
        Self {
            values: SmallVec::new(),
            names: SmallVec::new(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.values.is_empty() && self.names.is_empty()
    }

    pub fn add<T: ToValue>(&mut self, name: &str, value: T) {
        self.names.push(name.into());
        self.values.push(value.to_value());
    }

    pub fn get<T: FromValue>(&self, name: &str) -> Option<T> {
        let value = self.names
            .iter()
            .enumerate()
            .find(|(_, n)| &***n == name)
            .and_then(|(pos, _)| self.values.get(pos).cloned());
        
        if let Some(value) = value {
            Some(FromValue::from_value(value).unwrap())
        } else {
            None
        }
    }

    pub fn register_function<S: Into<Box<str>> + Copy, A, R, F: RegisterFunction<A, R> + Copy>(&mut self, name: S, fun: F) {
        let fun = NativeFun::new(name, fun.arity(), fun.to_native_function(), fun.is_varidic());   

        self.names.push(name.into());
        self.values.push(Value::NativeFun(Rc::new(fun)));
    }
}

#[cfg(test)]
mod test {
    use super::State;

    #[test]
    fn test_state() {
        let mut state = State::new();

        state.add("x", 23u32);
        state.add("y", true);

        assert_eq!(state.get::<u32>("x").unwrap(), 23);
        assert_eq!(state.get::<bool>("y").unwrap(), true);

        assert_eq!(state.get::<String>("nothing"), None);

        println!("{:#?}", state);
    }
}