use wasm_bindgen::JsValue;
pub trait ToJs {
fn to_js(&self) -> JsValue;
fn to_js_property_value(&self) -> Option<JsValue> {
Some(self.to_js())
}
}
impl<T> ToJs for Option<T>
where
T: ToJs,
{
fn to_js(&self) -> JsValue {
if let Some(v) = self {
v.to_js()
} else {
JsValue::UNDEFINED
}
}
fn to_js_property_value(&self) -> Option<JsValue> {
self.as_ref().map(|v| v.to_js())
}
}
impl<'a, B: 'a + ?Sized + ToJs + ToOwned> ToJs for std::borrow::Cow<'a, B> {
fn to_js(&self) -> JsValue {
self.as_ref().to_js()
}
}
macro_rules! impl_to_js {
(deref_copy: $($n:ty)*) => ($(
impl ToJs for $n {
#[inline]
fn to_js(&self) -> JsValue {
JsValue::from(*self)
}
}
)*);
(into: $($n:ty)*) => ($(
impl ToJs for $n {
#[inline]
fn to_js(&self) -> JsValue {
JsValue::from(self)
}
}
)*);
}
impl_to_js! {
into:
str
String
js_sys::Intl::Collator
js_sys::Intl::DateTimeFormat
js_sys::Intl::NumberFormat
js_sys::Intl::PluralRules
js_sys::WebAssembly::CompileError
js_sys::WebAssembly::Global
js_sys::WebAssembly::Instance
js_sys::WebAssembly::LinkError
js_sys::WebAssembly::Memory
js_sys::WebAssembly::Module
js_sys::WebAssembly::RuntimeError
js_sys::WebAssembly::Table
js_sys::Array
js_sys::ArrayBuffer
js_sys::AsyncIterator
js_sys::BigInt
js_sys::BigInt64Array
js_sys::BigUint64Array
js_sys::Boolean
js_sys::DataView
js_sys::Date
js_sys::Error
js_sys::EvalError
js_sys::Float32Array
js_sys::Float64Array
js_sys::Function
js_sys::Generator
js_sys::Int8Array
js_sys::Int16Array
js_sys::Int32Array
js_sys::Iterator
js_sys::IteratorNext
js_sys::JsString
js_sys::Map
js_sys::Number
js_sys::Object
js_sys::Promise
js_sys::Proxy
js_sys::RangeError
js_sys::ReferenceError
js_sys::RegExp
js_sys::Set
js_sys::SharedArrayBuffer
js_sys::Symbol
js_sys::SyntaxError
js_sys::TypeError
js_sys::Uint8Array
js_sys::Uint8ClampedArray
js_sys::Uint16Array
js_sys::Uint32Array
js_sys::UriError
js_sys::WeakMap
js_sys::WeakSet
}
impl_to_js! {
deref_copy:
&str
i8 u8 i16 u16 i32 u32 f32 f64
i64 u64 i128 u128 isize usize
bool
}
impl<T: ToJs> ToJs for &T {
fn to_js(&self) -> JsValue {
(*self).to_js()
}
}
macro_rules! impl_js_for_iter {
($($t:tt)+) => {
$($t)+ {
#[inline]
fn to_js(&self) -> JsValue {
js_sys::Array::from_iter(self.iter().map(|v| v.to_js())).into()
}
}
};
}
impl_js_for_iter! { impl<T: ToJs> ToJs for Vec<T> }
impl_js_for_iter! { impl<T: ToJs> ToJs for &[T] }
impl_js_for_iter! { impl<N: ToJs, const S: usize> ToJs for [N; S] }
macro_rules! impl_js_for_tuple {
(@impl $arr_method:ident ( $($t:ident),+ $(,)? )) => {
impl<$($t: ToJs),+> ToJs for ($($t),+ ,) {
#[inline]
fn to_js(&self) -> JsValue {
#![allow(non_snake_case)]
let ($($t),+ ,) = self;
js_sys::Array::$arr_method(
$(&$t.to_js()),+
).into()
}
}
};
(@impl ( $($t:ident),+ $(,)? )) => {
impl<$($t: ToJs),+> ToJs for ($($t),+ ,) {
#[inline]
fn to_js(&self) -> JsValue {
#![allow(non_snake_case)]
let ($($t),+ ,) = self;
js_sys::Array::from_iter([
$($t.to_js()),+
]).into()
}
}
};
( $( $($arr_method:ident)? ( $($t:ident),+ $(,)? ) )* ) => {
$(
impl_js_for_tuple! { @impl $($arr_method)? ($($t),+ ,) }
)*
};
}
impl_js_for_tuple! {
of1(T0,)
of2(T0,T1)
of3(T0,T1,T2)
of4(T0,T1,T2,T3)
of5(T0,T1,T2,T3,T4)
(T0,T1,T2,T3,T4,T5)
(T0,T1,T2,T3,T4,T5,T6)
(T0,T1,T2,T3,T4,T5,T6,T7)
(T0,T1,T2,T3,T4,T5,T6,T7,T8)
(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9)
}
impl<T: ToJs> ToJs for Box<T> {
#[inline]
fn to_js(&self) -> JsValue {
self.as_ref().to_js()
}
}
impl ToJs for () {
fn to_js(&self) -> JsValue {
JsValue::UNDEFINED
}
}
impl ToJs for JsValue {
fn to_js(&self) -> JsValue {
self.clone()
}
}
impl<T: ?Sized> ToJs for wasm_bindgen::prelude::Closure<T> {
fn to_js(&self) -> JsValue {
AsRef::<JsValue>::as_ref(&self).clone()
}
}