1use crate::error::Error;
7use crate::extensions::jsvalue::*;
8use js_sys::{Array, Reflect, Uint8Array};
9use wasm_bindgen::prelude::*;
10
11pub fn apply_with_args0(this_jsv: &JsValue, fn_name: &str) -> Result<JsValue, JsValue> {
13 let fn_jsv = Reflect::get(this_jsv, &JsValue::from(fn_name))?;
14 let args = Array::new();
15 let ret_jsv = Reflect::apply(&fn_jsv.into(), this_jsv, &args)?;
16 Ok(ret_jsv)
17}
18
19pub fn apply_with_args1(
21 this_jsv: &JsValue,
22 fn_name: &str,
23 arg_jsv: JsValue,
24) -> Result<JsValue, JsValue> {
25 let fn_jsv = Reflect::get(this_jsv, &JsValue::from(fn_name))?;
26 let args = Array::new_with_length(1);
27 args.set(0, arg_jsv);
28 let ret_jsv = Reflect::apply(&fn_jsv.into(), this_jsv, &args)?;
29 Ok(ret_jsv)
30}
31
32pub fn apply_with_args2(
34 this_jsv: &JsValue,
35 fn_name: &str,
36 arg_jsv: JsValue,
37 arg2_jsv: JsValue,
38) -> Result<JsValue, JsValue> {
39 let fn_jsv = Reflect::get(this_jsv, &JsValue::from(fn_name))?;
40 let args = Array::new_with_length(2);
41 args.set(0, arg_jsv);
42 args.set(1, arg2_jsv);
43 let ret_jsv = Reflect::apply(&fn_jsv.into(), this_jsv, &args)?;
44 Ok(ret_jsv)
45}
46
47#[inline]
50pub fn try_get_js_value_prop(jsv: &JsValue, prop: &str) -> Result<JsValue, Error> {
51 let v = Reflect::get(jsv, &JsValue::from(prop))
52 .map_err(|_| Error::PropertyAccess(prop.to_string()))?;
53 if v == JsValue::UNDEFINED {
54 return Err(Error::MissingProperty(prop.to_string()));
55 }
56 Ok(v)
57}
58
59#[inline]
62pub fn try_get_u64_from_prop(jsv: &JsValue, prop: &str) -> Result<u64, Error> {
63 let v = try_get_js_value_prop(jsv, prop)?;
64 if v.is_bigint() {
65 Ok(v.clone().try_into().map_err(|err| {
66 Error::Convert(format!(
67 "unable to convert property `{prop}` (BigInt) value: `{v:?}`: {err:?}"
68 ))
69 })?)
70 } else {
71 Ok(v.as_f64()
72 .ok_or_else(|| Error::WrongType(format!("property `{prop}` is not a number ({v:?})")))?
73 as u64)
74 }
75}
76
77#[inline]
80pub fn try_get_f64_from_prop(jsv: &JsValue, prop: &str) -> Result<f64, Error> {
81 let v = try_get_js_value_prop(jsv, prop)?;
82 let f = v
83 .as_f64()
84 .ok_or_else(|| Error::WrongType(format!("property `{prop}` is not a number ({v:?})")))?;
85 Ok(f)
86}
87
88#[inline]
91pub fn try_get_u8_from_prop(jsv: &JsValue, prop: &str) -> Result<u8, Error> {
92 try_get_js_value_prop(jsv, prop)?
93 .try_as_u8()
94 .map_err(|err| {
95 Error::WrongType(format!("unable to convert property `{prop}` to u8: {err}"))
96 })
97}
98
99#[inline]
102pub fn try_get_u16_from_prop(jsv: &JsValue, prop: &str) -> Result<u16, Error> {
103 try_get_js_value_prop(jsv, prop)?
104 .try_as_u16()
105 .map_err(|err| Error::Convert(format!("unable to convert property `{prop}` to u16: {err}")))
106}
107
108#[inline]
110pub fn try_get_u32_from_prop(jsv: &JsValue, prop: &str) -> Result<u32, Error> {
111 try_get_js_value_prop(jsv, prop)?
112 .try_as_u32()
113 .map_err(|err| Error::Convert(format!("unable to convert property `{prop}` to u32: {err}")))
114}
115
116#[inline]
118pub fn try_get_bool_from_prop(jsv: &JsValue, prop: &str) -> Result<bool, Error> {
119 try_get_js_value_prop(jsv, prop)?
120 .as_bool()
121 .ok_or_else(|| Error::WrongType(format!("property {prop} is not a boolean",)))
122}
123
124#[inline]
126pub fn try_get_vec_u8_from_number_array_prop(jsv: &JsValue, prop: &str) -> Result<Vec<u8>, Error> {
127 if try_get_js_value_prop(jsv, prop)?.is_array() {
128 let array = Array::from(jsv);
129 let array: Result<Vec<u8>, Error> = array.to_vec().iter().map(|v| v.try_as_u8()).collect();
130 Ok(array?)
131 } else {
132 Err(Error::WrongType(format!(
133 "try_get_vec_u8_from_number_array_prop: property {prop} is not an array"
134 )))
135 }
136}
137
138#[inline]
140pub fn try_get_vec_from_prop(jsv: &JsValue, prop: &str) -> Result<Vec<JsValue>, Error> {
141 let array = try_get_js_value_prop(jsv, prop)?.dyn_into::<Array>()?;
142 Ok(array.to_vec())
143}
144
145#[inline]
147pub fn try_get_vec_u8_from_uint8_array_prop(jsv: &JsValue, prop: &str) -> Result<Vec<u8>, Error> {
148 let buffer = try_get_js_value_prop(jsv, prop)?;
149 let array = Uint8Array::new(&buffer);
150 let data: Vec<u8> = array.to_vec();
151 Ok(data)
152}
153
154#[inline]
156pub fn try_get_vec_u8_from_bn_prop(jsv: &JsValue, prop: &str) -> Result<Vec<u8>, Error> {
157 let bn_jsv = try_get_js_value_prop(jsv, prop)?;
158 let bytes = apply_with_args0(&bn_jsv, "toBytes")?;
159 let array = Uint8Array::new(&bytes);
160 Ok(array.to_vec())
161}
162
163#[inline]
165pub fn try_get_vec_u8_from_bn(bn_jsv: &JsValue) -> Result<Vec<u8>, Error> {
166 let bytes = apply_with_args0(bn_jsv, "toBytes")?;
167 let array = Uint8Array::new(&bytes);
168 Ok(array.to_vec())
169}
170
171#[inline]
173pub fn try_get_string_from_prop(jsv: &JsValue, prop: &str) -> Result<String, Error> {
174 match try_get_js_value_prop(jsv, prop)?.as_string() {
175 Some(str) => Ok(str),
176 None => Err(Error::WrongType(format!(
177 "property '{prop}' is not a string",
178 ))),
179 }
180}