use anyhow::Result;
use js_sys::Number;
use wasm_bindgen::JsValue;
use super::StoreInner;
pub trait FromJs {
fn from_js(value: JsValue) -> Option<Self>
where
Self: Sized;
}
pub trait ToStoredJs {
type Repr: Into<JsValue>;
fn to_stored_js<T>(&self, store: &StoreInner<T>) -> Result<Self::Repr>;
}
pub trait ToJs {
type Repr: Into<JsValue>;
fn to_js(&self) -> Self::Repr;
}
impl<V> ToStoredJs for V
where
V: ToJs,
{
type Repr = V::Repr;
fn to_stored_js<T>(&self, _: &StoreInner<T>) -> Result<Self::Repr> {
Ok(self.to_js())
}
}
macro_rules! conv_number {
($ty: ty) => {
impl ToJs for $ty {
type Repr = Number;
fn to_js(&self) -> Number {
From::from(*self)
}
}
impl FromJs for $ty {
fn from_js(value: JsValue) -> Option<Self> {
Some(value.as_f64()? as $ty)
}
}
};
($($ty: ty),*) => {
$(conv_number!{ $ty } )*
}
}
conv_number!(i32, f32, f64);
impl ToJs for i64 {
type Repr = JsValue;
fn to_js(&self) -> Self::Repr {
JsValue::from(*self as f64)
}
}
impl FromJs for i64 {
fn from_js(value: JsValue) -> Option<Self>
where
Self: Sized,
{
value.try_into().ok()
}
}
impl FromJs for bool {
fn from_js(value: JsValue) -> Option<Self>
where
Self: Sized,
{
value.as_bool()
}
}
impl ToJs for bool {
type Repr = JsValue;
fn to_js(&self) -> Self::Repr {
JsValue::from(*self)
}
}