Expose primitive information about JsObject

Adds bindings for wbindgen to fill in via JS bindings to read the various
primitive properties of a JS value.
This commit is contained in:
Alex Crichton
2017-12-31 15:45:47 -08:00
parent 996c296de8
commit 0b81185c99
3 changed files with 391 additions and 48 deletions

View File

@ -9,6 +9,7 @@
extern crate wasm_bindgen_macro;
use std::mem;
use std::ptr;
/// A module which is typically glob imported from:
///
@ -31,7 +32,7 @@ pub struct JsObject {
}
impl JsObject {
/// Creates a new JS object which is a string.
/// Creates a new JS value which is a string.
///
/// The utf-8 string provided is copied to the JS heap and the string will
/// be owned by the JS garbage collector.
@ -41,6 +42,52 @@ impl JsObject {
}
}
/// Creates a new JS value which is a number.
///
/// This function creates a JS value representing a number (a heap
/// allocated number) and returns a handle to the JS version of it.
pub fn from_f64(n: f64) -> JsObject {
unsafe {
JsObject::__from_idx(__wbindgen_number_new(n))
}
}
/// Creates a new JS value which is a boolean.
///
/// This function creates a JS object representing a boolean (a heap
/// allocated boolean) and returns a handle to the JS version of it.
pub fn from_bool(b: bool) -> JsObject {
unsafe {
JsObject::__from_idx(__wbindgen_boolean_new(b as u32))
}
}
/// Creates a new JS value representing `undefined`.
pub fn undefined() -> JsObject {
unsafe {
JsObject::__from_idx(__wbindgen_undefined_new())
}
}
/// Creates a new JS value representing `null`.
pub fn null() -> JsObject {
unsafe {
JsObject::__from_idx(__wbindgen_null_new())
}
}
/// Creates a new JS symbol with the optional description specified.
///
/// This function will invoke the `Symbol` constructor in JS and return the
/// JS object corresponding to the symbol created.
pub fn symbol(description: Option<&str>) -> JsObject {
unsafe {
let ptr = description.map(|s| s.as_ptr()).unwrap_or(ptr::null());
let len = description.map(|s| s.len()).unwrap_or(0);
JsObject::__from_idx(__wbindgen_symbol_new(ptr, len))
}
}
#[doc(hidden)]
pub fn __from_idx(idx: u32) -> JsObject {
JsObject { idx }
@ -57,6 +104,77 @@ impl JsObject {
mem::forget(self);
return ret
}
/// Returns the `f64` value of this JS value if it's an instance of a
/// number.
///
/// If this JS value is not an instance of a number then this returns
/// `None`.
pub fn as_f64(&self) -> Option<f64> {
let mut invalid = 0;
unsafe {
let ret = __wbindgen_number_get(self.idx, &mut invalid);
if invalid == 1 {
None
} else {
Some(ret)
}
}
}
/// Returns the `String` of this JS value if it's an instance of a
/// string and it's valid utf-8.
///
/// If this JS value is not an instance of a string or if it's not valid
/// utf-8 then this returns `None`.
pub fn as_string(&self) -> Option<String> {
unsafe {
let mut len = 0;
let ptr = __wbindgen_string_get(self.idx, &mut len);
if ptr.is_null() {
None
} else {
let data = Vec::from_raw_parts(ptr, len, len);
Some(String::from_utf8_unchecked(data))
}
}
}
/// Returns the `bool` value of this JS value if it's an instance of a
/// boolean.
///
/// If this JS value is not an instance of a boolean then this returns
/// `None`.
pub fn as_bool(&self) -> Option<bool> {
unsafe {
match __wbindgen_boolean_get(self.idx) {
0 => Some(false),
1 => Some(true),
_ => None,
}
}
}
/// Tests whether this JS value is `null`
pub fn is_null(&self) -> bool {
unsafe {
__wbindgen_is_null(self.idx) == 1
}
}
/// Tests whether this JS value is `undefined`
pub fn is_undefined(&self) -> bool {
unsafe {
__wbindgen_is_undefined(self.idx) == 1
}
}
/// Tests whether the type of this JS value is `symbol`
pub fn is_symbol(&self) -> bool {
unsafe {
__wbindgen_is_symbol(self.idx) == 1
}
}
}
impl<'a> From<&'a str> for JsObject {
@ -65,10 +183,45 @@ impl<'a> From<&'a str> for JsObject {
}
}
impl<'a> From<&'a String> for JsObject {
fn from(s: &'a String) -> JsObject {
JsObject::from_str(s)
}
}
impl From<bool> for JsObject {
fn from(s: bool) -> JsObject {
JsObject::from_bool(s)
}
}
macro_rules! numbers {
($($n:ident)*) => ($(
impl From<$n> for JsObject {
fn from(n: $n) -> JsObject {
JsObject::from_f64(n.into())
}
}
)*)
}
numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
extern {
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_number_get(idx: u32, invalid: *mut u8) -> f64;
fn __wbindgen_null_new() -> u32;
fn __wbindgen_undefined_new() -> u32;
fn __wbindgen_is_null(idx: u32) -> u32;
fn __wbindgen_is_undefined(idx: u32) -> u32;
fn __wbindgen_boolean_new(val: u32) -> u32;
fn __wbindgen_boolean_get(idx: u32) -> u32;
fn __wbindgen_symbol_new(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_is_symbol(idx: u32) -> u32;
fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8;
}
impl Clone for JsObject {