pinar 0.1.0

Library to write node native modules with N-API
Documentation

use std::hash::Hash;
use std::collections::HashMap;
use std::sync::Arc;
use std::rc::Rc;
use std::hash::BuildHasher;
use crate::prelude::*;
use crate::Result;

pub trait ToJs<'e> {
    type Value: JsValue;
    fn to_js(self, _: Env) -> Result<Self::Value>;
}

macro_rules! impl_tojs {
    (
        $( $jstype:ident ),*
    ) => {
        $(
            impl<'e, 'v> ToJs<'e> for $jstype<'v> {
                type Value = Self;
                fn to_js(self, _: Env) -> Result<Self> {
                    Ok(self)
                }
            }
        )*
    }
}

impl_tojs!(
    JsString,
    JsObject,
    JsArray,
    JsNumber,
    JsSymbol,
    JsUndefined,
    JsFunction,
    JsExternal,
    JsNull,
    JsBoolean,
    JsBigInt
);

impl<'e> ToJs<'e> for Value {
    type Value = Self;
    fn to_js(self, _: Env) -> Result<Self> {
        Ok(self)
    }
}

impl<'e> ToJs<'e> for i64 {
    type Value = JsNumber<'e>;
    fn to_js(self, env: Env) -> Result<JsNumber<'e>> {
        env.number(self)
    }
}

impl<'e> ToJs<'e> for String {
    type Value = JsString<'e>;
    fn to_js(self, env: Env) -> Result<JsString<'e>> {
        env.string(self)
    }
}

impl<'e, K, V, S> ToJs<'e> for HashMap<K, V, S>
where
    K: Hash + Eq + KeyProperty + ToJs<'e>,
    V: ToJs<'e>,
    S: BuildHasher
{
    type Value = JsObject<'e>;
    fn to_js(self, env: Env) -> Result<JsObject<'e>> {
        let object = env.object()?;
        for (key, value) in self.into_iter() {
            object.set(key, value)?;
        }
        Ok(object)
    }
}

impl<'e, T> ToJs<'e> for std::vec::Vec<T>
where
    T: ToJs<'e>
{
    type Value = JsArray<'e>;
    fn to_js(self, env: Env) -> Result<JsArray<'e>> {
        let array = env.array_with_capacity(self.len())?;
        for (index, value) in self.into_iter().enumerate() {
            array.set(index as u32, value)?;
        }
        Ok(array)
    }
}

impl<'e, 's> ToJs<'e> for &'s str {
    type Value = JsString<'e>;
    fn to_js(self, env: Env) -> Result<JsString<'e>> {
        env.string(self)
    }
}

impl<'e, T: 'static> ToJs<'e> for Box<T> {
    type Value = JsExternal<'e>;
    fn to_js(self, env: Env) -> Result<JsExternal<'e>> {
        env.external_box(self)
    }
}

impl<'e, T: 'static> ToJs<'e> for Rc<T> {
    type Value = JsExternal<'e>;
    fn to_js(self, env: Env) -> Result<JsExternal<'e>> {
        env.external_rc(self)
    }
}

impl<'e, T: 'static> ToJs<'e> for Arc<T> {
    type Value = JsExternal<'e>;
    fn to_js(self, env: Env) -> Result<JsExternal<'e>> {
        env.external_arc(self)
    }
}