1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
use std::fmt;
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
#[derive(Clone, Debug)]
pub enum MyError {
Variant,
InflightShouldBeFalse,
}
// shouldn't technically need this, surely
impl std::error::Error for MyError {}
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "MyError::{:?}", self)
}
}
#[wasm_bindgen(module = "tests/wasm/result.js")]
extern "C" {
fn error_new(message: &str) -> JsValue;
}
impl From<MyError> for JsValue {
fn from(e: MyError) -> Self {
error_new(&format!("{}", e))
}
}
macro_rules! call_test {
($test_fn:ident, $js_fn:ident) => {
#[wasm_bindgen_test]
fn $test_fn() {
#[wasm_bindgen(module = "tests/wasm/result.js")]
extern "C" {
fn $js_fn();
}
$js_fn();
}
};
}
#[wasm_bindgen]
pub fn return_my_err() -> Result<i32, MyError> {
let e = Err(MyError::Variant)?;
Ok(e)
}
call_test!(test_err, call_err);
#[wasm_bindgen]
pub fn return_my_ok() -> Result<i32, MyError> {
Ok(5)
}
call_test!(test_ok, call_ok);
#[wasm_bindgen]
pub struct Struct {
inflight: bool,
}
call_test!(test_struct, all_struct_methods);
struct ResetOnDrop<'a> {
flag: &'a mut bool,
}
impl<'a> Drop for ResetOnDrop<'a> {
fn drop(&mut self) {
*self.flag = false;
}
}
impl<'a> ResetOnDrop<'a> {
fn new(flag: &'a mut bool) -> Result<Self, MyError> {
if *flag {
return Err(MyError::InflightShouldBeFalse);
}
Ok(Self { flag })
}
}
#[wasm_bindgen]
impl Struct {
#[wasm_bindgen]
pub fn new() -> Result<Struct, MyError> {
Ok(Struct { inflight: false })
}
#[wasm_bindgen]
pub fn new_err() -> Result<Struct, MyError> {
Err(MyError::Variant)
}
#[wasm_bindgen]
pub fn return_ok(&mut self) -> Result<i32, MyError> {
let _guard = ResetOnDrop::new(&mut self.inflight)?;
Ok(5)
}
#[wasm_bindgen]
pub fn return_err(&mut self) -> Result<i32, MyError> {
let guard = ResetOnDrop::new(&mut self.inflight)?;
let err = Err(MyError::Variant);
let nope = err?;
// we are checking both for the flag being reset (from js, via is_inflight)
// and for the running of drop code
drop(guard);
Ok(nope)
}
#[wasm_bindgen]
pub fn is_inflight(&self) -> bool {
self.inflight
}
}
// check some more Ok types
#[wasm_bindgen]
pub fn return_string() -> Result<String, MyError> {
Ok("string here".into())
}
call_test!(test_return_string, call_return_string);
// now we check that jsvalue works, as it did before
#[wasm_bindgen]
pub fn return_jsvalue_ok() -> Result<i32, JsValue> {
Ok(5)
}
call_test!(test_jsvalue_ok, call_jsvalue_ok);
#[wasm_bindgen]
pub fn return_jsvalue_err() -> Result<i32, JsValue> {
Err(JsValue::from(-1i32))
}
call_test!(test_jsvalue_err, call_jsvalue_err);
// test strings (they have a deferred free, in a finally block: tricky)
#[wasm_bindgen]
pub fn return_string_ok() -> Result<String, String> {
Ok("Ok".into())
}
call_test!(test_string_ok, call_string_ok);
#[wasm_bindgen]
pub fn return_string_err() -> Result<String, String> {
Err("Er".into())
}
call_test!(test_string_err, call_string_err);
// test enums
#[wasm_bindgen]
pub enum MyEnum {
One = 1,
Two = 2,
}
#[wasm_bindgen]
pub fn return_enum_ok() -> Result<MyEnum, MyError> {
Ok(MyEnum::Two)
}
call_test!(test_enum_ok, call_enum_ok);
#[wasm_bindgen]
pub fn return_enum_err() -> Result<MyEnum, MyError> {
Err(MyError::Variant)
}
call_test!(test_enum_err, call_enum_err);
// T = Unit
#[wasm_bindgen]
pub fn return_unit_ok() -> Result<(), MyError> {
Ok(())
}
#[wasm_bindgen]
pub fn return_unit_err() -> Result<(), MyError> {
Err(MyError::Variant)
}
call_test!(test_unit, call_unit);
// T = Option<f64>
#[wasm_bindgen]
pub fn return_option_ok_some() -> Result<Option<f64>, MyError> {
Ok(Some(10f64))
}
#[wasm_bindgen]
pub fn return_option_ok_none() -> Result<Option<f64>, MyError> {
Ok(None)
}
#[wasm_bindgen]
pub fn return_option_err() -> Result<Option<f64>, MyError> {
Err(MyError::Variant)
}
call_test!(test_option, call_option);
|