jsbind 0.1.44

Bindings for basic JS types required for webbind
Documentation
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use emlite::FromVal;

/// WebIDL `record<K, V>` wrapper. No concrete JS type, but needed for WebIDL
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Record<K, V> {
    inner: emlite::Val,
    _phantom: PhantomData<(K, V)>,
}

impl<K, V> emlite::FromVal for Record<K, V> {
    fn from_val(v: &emlite::Val) -> Self {
        Self {
            inner: v.clone(),
            _phantom: PhantomData,
        }
    }
    fn take_ownership(v: emlite::common::Handle) -> Self {
        Self::from_val(&emlite::Val::take_ownership(v))
    }
    fn as_handle(&self) -> emlite::common::Handle {
        self.inner.as_handle()
    }
}

impl<K, V> From<Record<K, V>> for emlite::Val {
    fn from(x: Record<K, V>) -> emlite::Val {
        let handle = x.inner.as_handle();
        core::mem::forget(x);
        emlite::Val::take_ownership(handle)
    }
}

impl<K, V> From<&Record<K, V>> for emlite::Val {
    fn from(x: &Record<K, V>) -> emlite::Val {
        x.inner.clone()
    }
}

impl<K, V> Deref for Record<K, V> {
    type Target = emlite::Val;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl<K, V> DerefMut for Record<K, V> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.inner
    }
}

impl<K, V> AsRef<emlite::Val> for Record<K, V> {
    fn as_ref(&self) -> &emlite::Val {
        &self.inner
    }
}

impl<K, V> AsMut<emlite::Val> for Record<K, V> {
    fn as_mut(&mut self) -> &mut emlite::Val {
        &mut self.inner
    }
}

impl<K, V> Default for Record<K, V> {
    fn default() -> Self {
        Self::new()
    }
}

impl<K, V> Record<K, V> {
    pub fn new() -> Self {
        Self {
            inner: emlite::Val::object(),
            _phantom: PhantomData,
        }
    }
    /// Set keyed `item` to `val`
    pub fn set(&self, item: K, val: V)
    where
        emlite::Val: From<K>,
        emlite::Val: From<V>,
    {
        self.inner.set(item, val);
    }

    /// Get the value of the key `item`
    pub fn get(&self, item: K) -> Option<V>
    where
        emlite::Val: From<K>,
        emlite::Val: From<V>,
        V: FromVal,
    {
        let v = self.inner.get(item);
        if v.is_undefined() {
            None
        } else {
            Some(v.as_::<V>())
        }
    }

    /// Returns whether a value exists in the Record.
    pub fn has(&self, item: K) -> bool
    where
        emlite::Val: From<K>,
    {
        self.inner.has(item)
    }

    /// Gets the number of properties in the object
    /// Note: JavaScript objects don't have a built-in size property like arrays,
    /// so this counts enumerable properties using Object.keys()
    pub fn size(&self) -> usize {
        let keys = emlite::Val::global("Object").call("keys", &[self.inner.clone()]);
        keys.get("length").as_::<usize>()
    }
}