#![no_std]
#![allow(coherence_leak_check)]
#![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
#![cfg_attr(feature = "nightly", feature(unsize))]
use core::fmt;
use core::marker;
use core::mem;
use core::ops::{Deref, DerefMut};
use crate::convert::{FromWasmAbi, WasmOptionalF64, WasmSlice};
macro_rules! if_std {
($($i:item)*) => ($(
#[cfg(feature = "std")] $i
)*)
}
macro_rules! externs {
($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
$(#[$attr])*
extern "C" {
$(fn $name($($args)*) -> $ret;)*
}
$(
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
#[allow(unused_variables)]
unsafe extern fn $name($($args)*) -> $ret {
panic!("function not implemented on non-wasm32 targets")
}
)*
)
}
pub mod prelude {
pub use crate::JsValue;
pub use crate::UnwrapThrowExt;
#[doc(hidden)]
pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
pub use wasm_bindgen_macro::wasm_bindgen;
if_std! {
pub use crate::closure::Closure;
}
}
pub mod convert;
pub mod describe;
mod cast;
pub use crate::cast::JsCast;
if_std! {
extern crate std;
use std::prelude::v1::*;
pub mod closure;
mod externref;
mod cache;
pub use cache::intern::{intern, unintern};
}
pub struct JsValue {
idx: u32,
_marker: marker::PhantomData<*mut u8>, }
const JSIDX_OFFSET: u32 = 32; const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET + 0;
const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
impl JsValue {
pub const NULL: JsValue = JsValue {
idx: JSIDX_NULL,
_marker: marker::PhantomData,
};
pub const UNDEFINED: JsValue = JsValue {
idx: JSIDX_UNDEFINED,
_marker: marker::PhantomData,
};
pub const TRUE: JsValue = JsValue {
idx: JSIDX_TRUE,
_marker: marker::PhantomData,
};
pub const FALSE: JsValue = JsValue {
idx: JSIDX_FALSE,
_marker: marker::PhantomData,
};
#[inline]
fn _new(idx: u32) -> JsValue {
JsValue {
idx,
_marker: marker::PhantomData,
}
}
#[inline]
pub fn from_str(s: &str) -> JsValue {
unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
}
#[inline]
pub fn from_f64(n: f64) -> JsValue {
unsafe { JsValue::_new(__wbindgen_number_new(n)) }
}
#[inline]
pub fn from_bool(b: bool) -> JsValue {
if b {
JsValue::TRUE
} else {
JsValue::FALSE
}
}
#[inline]
pub fn undefined() -> JsValue {
JsValue::UNDEFINED
}
#[inline]
pub fn null() -> JsValue {
JsValue::NULL
}
pub fn symbol(description: Option<&str>) -> JsValue {
unsafe {
match description {
Some(description) => JsValue::_new(__wbindgen_symbol_named_new(
description.as_ptr(),
description.len(),
)),
None => JsValue::_new(__wbindgen_symbol_anonymous_new()),
}
}
}
#[cfg(feature = "serde-serialize")]
pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
where
T: serde::ser::Serialize + ?Sized,
{
let s = serde_json::to_string(t)?;
unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
}
#[cfg(feature = "serde-serialize")]
pub fn into_serde<T>(&self) -> serde_json::Result<T>
where
T: for<'a> serde::de::Deserialize<'a>,
{
unsafe {
let ret = __wbindgen_json_serialize(self.idx);
let s = String::from_abi(ret);
serde_json::from_str(&s)
}
}
pub fn as_f64(&self) -> Option<f64> {
unsafe { FromWasmAbi::from_abi(__wbindgen_number_get(self.idx)) }
}
pub fn is_string(&self) -> bool {
unsafe { __wbindgen_is_string(self.idx) == 1 }
}
#[cfg(feature = "std")]
pub fn as_string(&self) -> Option<String> {
unsafe { FromWasmAbi::from_abi(__wbindgen_string_get(self.idx)) }
}
pub fn as_bool(&self) -> Option<bool> {
unsafe {
match __wbindgen_boolean_get(self.idx) {
0 => Some(false),
1 => Some(true),
_ => None,
}
}
}
#[inline]
pub fn is_null(&self) -> bool {
unsafe { __wbindgen_is_null(self.idx) == 1 }
}
#[inline]
pub fn is_undefined(&self) -> bool {
unsafe { __wbindgen_is_undefined(self.idx) == 1 }
}
#[inline]
pub fn is_symbol(&self) -> bool {
unsafe { __wbindgen_is_symbol(self.idx) == 1 }
}
#[inline]
pub fn is_object(&self) -> bool {
unsafe { __wbindgen_is_object(self.idx) == 1 }
}
#[inline]
pub fn is_function(&self) -> bool {
unsafe { __wbindgen_is_function(self.idx) == 1 }
}
#[inline]
pub fn is_truthy(&self) -> bool {
!self.is_falsy()
}
#[inline]
pub fn is_falsy(&self) -> bool {
unsafe { __wbindgen_is_falsy(self.idx) == 1 }
}
#[cfg(feature = "std")]
fn as_debug_string(&self) -> String {
unsafe {
let mut ret = [0; 2];
__wbindgen_debug_string(&mut ret, self.idx);
let data = Vec::from_raw_parts(ret[0] as *mut u8, ret[1], ret[1]);
String::from_utf8_unchecked(data)
}
}
}
impl PartialEq for JsValue {
#[inline]
fn eq(&self, other: &JsValue) -> bool {
unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
}
}
impl PartialEq<bool> for JsValue {
#[inline]
fn eq(&self, other: &bool) -> bool {
self.as_bool() == Some(*other)
}
}
impl PartialEq<str> for JsValue {
#[inline]
fn eq(&self, other: &str) -> bool {
*self == JsValue::from_str(other)
}
}
impl<'a> PartialEq<&'a str> for JsValue {
#[inline]
fn eq(&self, other: &&'a str) -> bool {
<JsValue as PartialEq<str>>::eq(self, other)
}
}
if_std! {
impl PartialEq<String> for JsValue {
#[inline]
fn eq(&self, other: &String) -> bool {
<JsValue as PartialEq<str>>::eq(self, other)
}
}
impl<'a> PartialEq<&'a String> for JsValue {
#[inline]
fn eq(&self, other: &&'a String) -> bool {
<JsValue as PartialEq<str>>::eq(self, other)
}
}
}
impl<'a> From<&'a str> for JsValue {
#[inline]
fn from(s: &'a str) -> JsValue {
JsValue::from_str(s)
}
}
if_std! {
impl<'a> From<&'a String> for JsValue {
#[inline]
fn from(s: &'a String) -> JsValue {
JsValue::from_str(s)
}
}
impl From<String> for JsValue {
#[inline]
fn from(s: String) -> JsValue {
JsValue::from_str(&s)
}
}
}
impl From<bool> for JsValue {
#[inline]
fn from(s: bool) -> JsValue {
JsValue::from_bool(s)
}
}
impl<'a, T> From<&'a T> for JsValue
where
T: JsCast,
{
#[inline]
fn from(s: &'a T) -> JsValue {
s.as_ref().clone()
}
}
impl<T> From<Option<T>> for JsValue
where
JsValue: From<T>,
{
#[inline]
fn from(s: Option<T>) -> JsValue {
match s {
Some(s) => s.into(),
None => JsValue::undefined(),
}
}
}
impl JsCast for JsValue {
#[inline]
fn instanceof(_val: &JsValue) -> bool {
true
}
#[inline]
fn unchecked_from_js(val: JsValue) -> Self {
val
}
#[inline]
fn unchecked_from_js_ref(val: &JsValue) -> &Self {
val
}
}
impl AsRef<JsValue> for JsValue {
#[inline]
fn as_ref(&self) -> &JsValue {
self
}
}
macro_rules! numbers {
($($n:ident)*) => ($(
impl PartialEq<$n> for JsValue {
#[inline]
fn eq(&self, other: &$n) -> bool {
self.as_f64() == Some(f64::from(*other))
}
}
impl From<$n> for JsValue {
#[inline]
fn from(n: $n) -> JsValue {
JsValue::from_f64(n.into())
}
}
)*)
}
numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
externs! {
#[link(wasm_import_module = "__wbindgen_placeholder__")]
extern "C" {
fn __wbindgen_object_clone_ref(idx: u32) -> u32;
fn __wbindgen_object_drop_ref(idx: u32) -> ();
fn __wbindgen_string_new(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_number_new(f: f64) -> u32;
fn __wbindgen_symbol_named_new(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_symbol_anonymous_new() -> u32;
fn __wbindgen_externref_heap_live_count() -> u32;
fn __wbindgen_is_null(idx: u32) -> u32;
fn __wbindgen_is_undefined(idx: u32) -> u32;
fn __wbindgen_is_symbol(idx: u32) -> u32;
fn __wbindgen_is_object(idx: u32) -> u32;
fn __wbindgen_is_function(idx: u32) -> u32;
fn __wbindgen_is_string(idx: u32) -> u32;
fn __wbindgen_is_falsy(idx: u32) -> u32;
fn __wbindgen_number_get(idx: u32) -> WasmOptionalF64;
fn __wbindgen_boolean_get(idx: u32) -> u32;
fn __wbindgen_string_get(idx: u32) -> WasmSlice;
fn __wbindgen_debug_string(ret: *mut [usize; 2], idx: u32) -> ();
fn __wbindgen_throw(a: *const u8, b: usize) -> !;
fn __wbindgen_rethrow(a: u32) -> !;
fn __wbindgen_cb_drop(idx: u32) -> u32;
fn __wbindgen_describe(v: u32) -> ();
fn __wbindgen_describe_closure(a: u32, b: u32, c: u32) -> u32;
fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_json_serialize(idx: u32) -> WasmSlice;
fn __wbindgen_jsval_eq(a: u32, b: u32) -> u32;
fn __wbindgen_memory() -> u32;
fn __wbindgen_module() -> u32;
fn __wbindgen_function_table() -> u32;
}
}
impl Clone for JsValue {
#[inline]
fn clone(&self) -> JsValue {
unsafe {
let idx = __wbindgen_object_clone_ref(self.idx);
JsValue::_new(idx)
}
}
}
#[cfg(feature = "std")]
impl fmt::Debug for JsValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "JsValue({})", self.as_debug_string())
}
}
#[cfg(not(feature = "std"))]
impl fmt::Debug for JsValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("JsValue")
}
}
impl Drop for JsValue {
#[inline]
fn drop(&mut self) {
unsafe {
debug_assert!(self.idx >= JSIDX_OFFSET, "free of stack slot {}", self.idx);
if self.idx >= JSIDX_RESERVED {
__wbindgen_object_drop_ref(self.idx);
}
}
}
}
#[cfg(feature = "std")]
pub struct JsStatic<T: 'static> {
#[doc(hidden)]
pub __inner: &'static std::thread::LocalKey<T>,
}
#[cfg(feature = "std")]
impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
}
}
#[cold]
#[inline(never)]
#[deprecated(note = "renamed to `throw_str`")]
#[doc(hidden)]
pub fn throw(s: &str) -> ! {
throw_str(s)
}
#[cold]
#[inline(never)]
pub fn throw_str(s: &str) -> ! {
unsafe {
__wbindgen_throw(s.as_ptr(), s.len());
}
}
#[cold]
#[inline(never)]
pub fn throw_val(s: JsValue) -> ! {
unsafe {
let idx = s.idx;
mem::forget(s);
__wbindgen_rethrow(idx);
}
}
pub fn externref_heap_live_count() -> u32 {
unsafe { __wbindgen_externref_heap_live_count() }
}
#[doc(hidden)]
pub fn anyref_heap_live_count() -> u32 {
externref_heap_live_count()
}
pub trait UnwrapThrowExt<T>: Sized {
fn unwrap_throw(self) -> T {
self.expect_throw("`unwrap_throw` failed")
}
fn expect_throw(self, message: &str) -> T;
}
impl<T> UnwrapThrowExt<T> for Option<T> {
fn expect_throw(self, message: &str) -> T {
if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
match self {
Some(val) => val,
None => throw_str(message),
}
} else {
self.expect(message)
}
}
}
impl<T, E> UnwrapThrowExt<T> for Result<T, E>
where
E: core::fmt::Debug,
{
fn expect_throw(self, message: &str) -> T {
if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
match self {
Ok(val) => val,
Err(_) => throw_str(message),
}
} else {
self.expect(message)
}
}
}
#[doc(hidden)]
pub fn module() -> JsValue {
unsafe { JsValue::_new(__wbindgen_module()) }
}
pub fn memory() -> JsValue {
unsafe { JsValue::_new(__wbindgen_memory()) }
}
pub fn function_table() -> JsValue {
unsafe { JsValue::_new(__wbindgen_function_table()) }
}
#[doc(hidden)]
pub mod __rt {
use crate::JsValue;
use core::cell::{Cell, UnsafeCell};
use core::ops::{Deref, DerefMut};
pub extern crate core;
#[cfg(feature = "std")]
pub extern crate std;
#[macro_export]
#[doc(hidden)]
#[cfg(feature = "std")]
macro_rules! __wbindgen_if_not_std {
($($i:item)*) => {};
}
#[macro_export]
#[doc(hidden)]
#[cfg(not(feature = "std"))]
macro_rules! __wbindgen_if_not_std {
($($i:item)*) => ($($i)*)
}
#[inline]
pub fn assert_not_null<T>(s: *mut T) {
if s.is_null() {
throw_null();
}
}
#[cold]
#[inline(never)]
fn throw_null() -> ! {
super::throw_str("null pointer passed to rust");
}
pub struct WasmRefCell<T: ?Sized> {
borrow: Cell<usize>,
value: UnsafeCell<T>,
}
impl<T: ?Sized> WasmRefCell<T> {
pub fn new(value: T) -> WasmRefCell<T>
where
T: Sized,
{
WasmRefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(0),
}
}
pub fn get_mut(&mut self) -> &mut T {
unsafe { &mut *self.value.get() }
}
pub fn borrow(&self) -> Ref<T> {
unsafe {
if self.borrow.get() == usize::max_value() {
borrow_fail();
}
self.borrow.set(self.borrow.get() + 1);
Ref {
value: &*self.value.get(),
borrow: &self.borrow,
}
}
}
pub fn borrow_mut(&self) -> RefMut<T> {
unsafe {
if self.borrow.get() != 0 {
borrow_fail();
}
self.borrow.set(usize::max_value());
RefMut {
value: &mut *self.value.get(),
borrow: &self.borrow,
}
}
}
pub fn into_inner(self) -> T
where
T: Sized,
{
self.value.into_inner()
}
}
pub struct Ref<'b, T: ?Sized + 'b> {
value: &'b T,
borrow: &'b Cell<usize>,
}
impl<'b, T: ?Sized> Deref for Ref<'b, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'b, T: ?Sized> Drop for Ref<'b, T> {
fn drop(&mut self) {
self.borrow.set(self.borrow.get() - 1);
}
}
pub struct RefMut<'b, T: ?Sized + 'b> {
value: &'b mut T,
borrow: &'b Cell<usize>,
}
impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.value
}
}
impl<'b, T: ?Sized> Drop for RefMut<'b, T> {
fn drop(&mut self) {
self.borrow.set(0);
}
}
fn borrow_fail() -> ! {
super::throw_str(
"recursive use of an object detected which would lead to \
unsafe aliasing in rust",
);
}
if_std! {
use std::alloc::{alloc, dealloc, realloc, Layout};
use std::mem;
#[no_mangle]
pub extern "C" fn __wbindgen_malloc(size: usize) -> *mut u8 {
let align = mem::align_of::<usize>();
if let Ok(layout) = Layout::from_size_align(size, align) {
unsafe {
if layout.size() > 0 {
let ptr = alloc(layout);
if !ptr.is_null() {
return ptr
}
} else {
return align as *mut u8
}
}
}
malloc_failure();
}
#[no_mangle]
pub unsafe extern "C" fn __wbindgen_realloc(ptr: *mut u8, old_size: usize, new_size: usize) -> *mut u8 {
let align = mem::align_of::<usize>();
debug_assert!(old_size > 0);
debug_assert!(new_size > 0);
if let Ok(layout) = Layout::from_size_align(old_size, align) {
let ptr = realloc(ptr, layout, new_size);
if !ptr.is_null() {
return ptr
}
}
malloc_failure();
}
#[cold]
fn malloc_failure() -> ! {
if cfg!(debug_assertions) {
super::throw_str("invalid malloc request")
} else {
std::process::abort();
}
}
#[no_mangle]
pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize) {
if size == 0 {
return
}
let align = mem::align_of::<usize>();
let layout = Layout::from_size_align_unchecked(size, align);
dealloc(ptr, layout);
}
}
pub fn link_mem_intrinsics() {
crate::externref::link_intrinsics();
}
static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2];
#[no_mangle]
pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
debug_assert_eq!(GLOBAL_EXNDATA[0], 0);
GLOBAL_EXNDATA[0] = 1;
GLOBAL_EXNDATA[1] = idx;
}
pub fn take_last_exception() -> Result<(), super::JsValue> {
unsafe {
let ret = if GLOBAL_EXNDATA[0] == 1 {
Err(super::JsValue::_new(GLOBAL_EXNDATA[1]))
} else {
Ok(())
};
GLOBAL_EXNDATA[0] = 0;
GLOBAL_EXNDATA[1] = 0;
return ret;
}
}
pub trait IntoJsResult {
fn into_js_result(self) -> Result<JsValue, JsValue>;
}
impl IntoJsResult for () {
fn into_js_result(self) -> Result<JsValue, JsValue> {
Ok(JsValue::undefined())
}
}
impl<T: Into<JsValue>> IntoJsResult for T {
fn into_js_result(self) -> Result<JsValue, JsValue> {
Ok(self.into())
}
}
impl<T: Into<JsValue>, E: Into<JsValue>> IntoJsResult for Result<T, E> {
fn into_js_result(self) -> Result<JsValue, JsValue> {
match self {
Ok(e) => Ok(e.into()),
Err(e) => Err(e.into()),
}
}
}
impl<E: Into<JsValue>> IntoJsResult for Result<(), E> {
fn into_js_result(self) -> Result<JsValue, JsValue> {
match self {
Ok(()) => Ok(JsValue::undefined()),
Err(e) => Err(e.into()),
}
}
}
pub trait Start {
fn start(self);
}
impl Start for () {
#[inline]
fn start(self) {}
}
impl<E: Into<JsValue>> Start for Result<(), E> {
#[inline]
fn start(self) {
if let Err(e) = self {
crate::throw_val(e.into());
}
}
}
}
#[derive(Copy, Clone, PartialEq, Debug, Eq)]
pub struct Clamped<T>(pub T);
impl<T> Deref for Clamped<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> DerefMut for Clamped<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}