1#![no_std]
2#![allow(unused_unsafe)]
3#![allow(unused_imports)]
4#![allow(clippy::missing_safety_doc)]
5extern crate alloc;
6
7pub mod common;
8
9#[cfg(not(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component")))]
10pub mod env;
11#[cfg(not(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component")))]
12use crate::env::*;
13
14#[cfg(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component"))]
15pub mod wasip2env;
16#[cfg(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component"))]
17use crate::wasip2env::*;
18
19use crate::common::{EMLITE_TARGET, Handle};
20#[cfg(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component"))]
21use alloc::alloc::{Layout, alloc};
22use alloc::boxed::Box;
23use alloc::format;
24use alloc::string::String;
25use alloc::string::ToString;
26use alloc::vec::Vec;
27use core::ffi::CStr;
28
29#[repr(u32)]
30pub enum EmlitePredefHandles {
31 Null = 0,
32 Undefined,
33 False,
34 True,
35 GlobalThis,
36 Console,
37 Reserved,
38}
39
40#[macro_export]
42macro_rules! eval {
43 ($src: literal) => {{
44 $crate::Val::global("eval").invoke(&[$crate::Val::from($src)])
45 }};
46 ($src: literal $(, $arg:expr)* $(,)?) => {{
47 $crate::Val::global("eval").invoke(
48 &[$crate::Val::from(&format!($src, $( $arg ),*)) ]
49 )
50 }};
51}
52
53#[macro_export]
55macro_rules! argv {
56 ($($rest:expr),*) => {{
57 [$($crate::Val::from($rest)),*]
58 }};
59}
60
61pub fn init() {
62 unsafe {
63 #[cfg(not(target_os = "emscripten"))]
64 {
65 }
67 emlite_init_handle_table();
68 }
69}
70
71#[derive(Debug)]
73pub struct Val {
74 inner: Handle,
75}
76
77impl Val {
78 pub const fn global_this() -> Val {
80 Val {
81 inner: EmlitePredefHandles::GlobalThis as _,
82 }
83 }
84
85 pub fn get<T: Into<Val>>(&self, prop: T) -> Val {
87 let h = unsafe { emlite_val_get(self.as_handle(), prop.into().as_handle()) };
88 Val::take_ownership(h)
89 }
90
91 pub fn global(name: &str) -> Val {
93 Val::global_this().get(name)
94 }
95
96 pub const fn null() -> Val {
98 Val {
99 inner: EmlitePredefHandles::Null as _,
100 }
101 }
102
103 pub const fn undefined() -> Val {
105 Val {
106 inner: EmlitePredefHandles::Undefined as _,
107 }
108 }
109
110 pub fn object() -> Val {
112 Val::take_ownership(unsafe { emlite_val_new_object() })
113 }
114
115 pub fn array() -> Val {
117 Val::take_ownership(unsafe { emlite_val_new_array() })
118 }
119
120 pub fn from_slice<T>(slice: &[T]) -> Val
125 where
126 T: Clone + Into<Val>,
127 {
128 let arr = Val::array();
129 for item in slice {
130 arr.call("push", &[item.clone().into()]);
132 }
133 arr
134 }
135
136 pub fn set<K: Into<Val>, V: Into<Val>>(&self, prop: K, val: V) {
138 unsafe {
139 emlite_val_set(
140 self.as_handle(),
141 prop.into().as_handle(),
142 val.into().as_handle(),
143 )
144 };
145 }
146
147 pub fn has<T: Into<Val>>(&self, prop: T) -> bool {
149 unsafe { emlite_val_has(self.as_handle(), prop.into().as_handle()) }
150 }
151
152 pub fn has_own_property(&self, prop: &str) -> bool {
154 unsafe { emlite_val_obj_has_own_prop_unified(self.as_handle(), prop) }
155 }
156
157 pub fn type_of(&self) -> String {
159 unsafe { emlite_val_typeof_unified(self.as_handle()) }
160 }
161
162 pub fn at<T: Into<Val>>(&self, idx: T) -> Val {
164 Val::take_ownership(unsafe { emlite_val_get(self.as_handle(), idx.into().as_handle()) })
165 }
166
167 pub fn to_vec<V: FromVal>(&self) -> Vec<V> {
169 let len = self.get("length").as_::<usize>();
170 let mut v: Vec<V> = Vec::with_capacity(len);
171 for i in 0..len {
172 v.push(self.at::<i32>(i as _).as_::<V>());
173 }
174 v
175 }
176
177 pub fn call(&self, f: &str, args: &[Val]) -> Val {
179 unsafe {
180 let arr = Val::take_ownership(emlite_val_new_array());
181 for arg in args {
182 emlite_val_push(arr.as_handle(), arg.as_handle());
183 }
184 Val::take_ownership(emlite_val_obj_call_unified(
185 self.as_handle(),
186 f,
187 arr.as_handle(),
188 ))
189 }
190 }
191
192 pub fn new(&self, args: &[Val]) -> Val {
194 unsafe {
195 let arr = Val::take_ownership(emlite_val_new_array());
196 for arg in args {
197 emlite_val_push(arr.as_handle(), arg.as_handle());
198 }
199 Val::take_ownership(emlite_val_construct_new(self.as_handle(), arr.as_handle()))
200 }
201 }
202
203 pub fn invoke(&self, args: &[Val]) -> Val {
205 unsafe {
206 let arr = Val::take_ownership(emlite_val_new_array());
207 for arg in args {
208 emlite_val_push(arr.as_handle(), arg.as_handle());
209 }
210 Val::take_ownership(emlite_val_func_call(self.as_handle(), arr.as_handle()))
211 }
212 }
213
214 pub fn make_fn_raw(f: extern "C" fn(Handle, Handle) -> Handle, data: Handle) -> Val {
218 let idx = unsafe { emlite_register_callback_unified(f) };
219 #[cfg(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component"))]
220 unsafe {
221 emlite_val_inc_ref(data);
223
224 #[repr(C)]
226 struct Pack {
227 f: extern "C" fn(Handle, Handle) -> Handle,
228 user_data: Handle,
229 }
230 let pack_ptr = alloc(Layout::new::<Pack>()) as *mut Pack;
231 if pack_ptr.is_null() {
232 return Val::undefined();
234 }
235 (*pack_ptr).f = f;
236 (*pack_ptr).user_data = data;
237
238 let packed_handle = emlite_val_make_biguint(pack_ptr as usize as _);
240 Val::take_ownership(emlite_val_make_callback(idx, packed_handle))
242 }
243 #[cfg(not(all(target_os = "wasi", target_env = "p2", feature = "wasip2-component")))]
244 unsafe {
245 Val::take_ownership(emlite_val_make_callback(idx, data))
246 }
247 }
248
249 pub fn make_fn<F: FnMut(&[Val]) -> Val>(cb: F) -> Val {
251 extern "C" fn shim(args: Handle, data: Handle) -> Handle {
252 let v = Val::take_ownership(args);
253 let vals: Vec<Val> = v.to_vec();
254 let ptr_u = unsafe { emlite_val_get_value_biguint(data) } as usize;
256 let a = ptr_u as *mut Box<dyn FnMut(&[Val]) -> Val>;
257 let f: &mut (dyn FnMut(&[Val]) -> Val) = unsafe { &mut **a };
258 f(&vals).as_handle()
259 }
260 #[allow(clippy::type_complexity)]
261 let a: *mut Box<dyn FnMut(&[Val]) -> Val> = Box::into_raw(Box::new(Box::new(cb)));
262 let data = Val::from(a as usize);
264 unsafe {
265 emlite_val_inc_ref(data.as_handle());
266 }
267 Self::make_fn_raw(shim, data.as_handle())
268 }
269
270 pub fn await_(&self) -> Val {
272 eval!(
273 r#"
274 (async () => {{
275 let obj = EMLITE_VALMAP.toValue({});
276 let ret = await obj;
277 return EMLITE_VALMAP.toHandle(ret);
278 }})()
279 "#,
280 self.as_handle()
281 )
282 }
283
284 pub fn delete(v: Val) {
286 unsafe {
287 emlite_val_dec_ref(v.as_handle());
288 }
289 }
290
291 pub fn throw(v: Val) -> ! {
293 unsafe {
294 emlite_val_throw(v.as_handle());
295 }
296 }
297
298 pub fn instanceof(&self, v: Val) -> bool {
300 unsafe { emlite_val_instanceof(self.as_handle(), v.as_handle()) }
301 }
302
303 pub fn is_number(&self) -> bool {
304 unsafe { emlite_val_is_number(self.as_handle()) }
305 }
306
307 pub fn is_bool(&self) -> bool {
308 unsafe { emlite_val_is_bool(self.as_handle()) }
309 }
310
311 pub fn is_string(&self) -> bool {
312 unsafe { emlite_val_is_string(self.as_handle()) }
313 }
314
315 pub fn is_null(&self) -> bool {
316 self.as_handle() == EmlitePredefHandles::Null as u32
317 }
318
319 pub fn is_undefined(&self) -> bool {
320 self.as_handle() == EmlitePredefHandles::Undefined as u32
321 }
322
323 pub fn is_error(&self) -> bool {
324 self.instanceof(Val::global("Error"))
325 }
326
327 pub fn is_function(&self) -> bool {
328 self.instanceof(Val::global("Function"))
329 }
330
331 #[inline(always)]
332 pub fn as_<T>(&self) -> T
333 where
334 T: FromVal,
335 {
336 T::from_val(self)
337 }
338
339 pub fn from_utf16(utf16: &[u16]) -> Val {
341 Val::from(utf16)
342 }
343
344 pub fn to_utf16(&self) -> Option<Vec<u16>> {
346 self.as_::<Option<Vec<u16>>>()
347 }
348
349 pub fn to_utf16_result(&self) -> Result<Vec<u16>, Val> {
351 self.as_::<Result<Vec<u16>, Val>>()
352 }
353
354 #[allow(clippy::result_unit_err)]
356 pub fn utf16_to_string(utf16: &[u16]) -> Result<String, ()> {
357 match String::from_utf16(utf16) {
360 Ok(s) => Ok(s),
361 Err(_) => Err(()),
362 }
363 }
364
365 pub fn from_string_via_utf16(s: &str) -> Val {
367 let utf16: Vec<u16> = s.encode_utf16().collect();
368 Val::from_utf16(&utf16)
369 }
370}
371
372impl From<bool> for Val {
373 fn from(v: bool) -> Self {
374 Val::take_ownership(unsafe { emlite_val_make_bool(v as _) })
375 }
376}
377
378impl From<i8> for Val {
379 fn from(v: i8) -> Self {
380 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
381 }
382}
383
384impl From<u8> for Val {
385 fn from(v: u8) -> Self {
386 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
387 }
388}
389
390impl From<i16> for Val {
391 fn from(v: i16) -> Self {
392 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
393 }
394}
395
396impl From<u16> for Val {
397 fn from(v: u16) -> Self {
398 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
399 }
400}
401
402impl From<i32> for Val {
403 fn from(v: i32) -> Self {
404 Val::take_ownership(unsafe { emlite_val_make_int(v) })
405 }
406}
407
408impl From<u32> for Val {
409 fn from(v: u32) -> Self {
410 Val::take_ownership(unsafe { emlite_val_make_uint(v as _) })
411 }
412}
413
414impl From<i64> for Val {
415 fn from(v: i64) -> Self {
416 Val::take_ownership(unsafe { emlite_val_make_bigint(v as _) })
417 }
418}
419
420impl From<u64> for Val {
421 fn from(v: u64) -> Self {
422 Val::take_ownership(unsafe { emlite_val_make_biguint(v as _) })
423 }
424}
425
426impl From<usize> for Val {
427 fn from(v: usize) -> Self {
428 Val::take_ownership(unsafe { emlite_val_make_biguint(v as _) })
429 }
430}
431
432impl From<isize> for Val {
433 fn from(v: isize) -> Self {
434 Val::take_ownership(unsafe { emlite_val_make_bigint(v as _) })
435 }
436}
437
438impl From<f32> for Val {
439 fn from(v: f32) -> Self {
440 Val::take_ownership(unsafe { emlite_val_make_double(v as _) })
441 }
442}
443
444impl From<f64> for Val {
445 fn from(v: f64) -> Self {
446 Val::take_ownership(unsafe { emlite_val_make_double(v) })
447 }
448}
449
450impl From<()> for Val {
451 fn from(_: ()) -> Self {
452 Val::undefined()
453 }
454}
455
456impl From<&str> for Val {
457 fn from(s: &str) -> Self {
458 Val::take_ownership(unsafe { emlite_val_make_str_unified(s) })
459 }
460}
461
462impl From<String> for Val {
463 fn from(s: String) -> Self {
464 Val::take_ownership(unsafe { emlite_val_make_str_unified(&s) })
465 }
466}
467
468impl From<&String> for Val {
469 fn from(s: &String) -> Self {
470 Val::take_ownership(unsafe { emlite_val_make_str_unified(s) })
471 }
472}
473
474impl From<&[u16]> for Val {
475 fn from(s: &[u16]) -> Self {
476 Val::take_ownership(unsafe { emlite_val_make_str_utf16_unified(s) })
477 }
478}
479
480impl From<Vec<u16>> for Val {
481 fn from(s: Vec<u16>) -> Self {
482 Val::take_ownership(unsafe { emlite_val_make_str_utf16_unified(&s) })
483 }
484}
485
486impl From<&Vec<u16>> for Val {
487 fn from(s: &Vec<u16>) -> Self {
488 Val::take_ownership(unsafe { emlite_val_make_str_utf16_unified(s) })
489 }
490}
491
492impl From<&Val> for Val {
493 fn from(v: &Val) -> Self {
494 v.clone()
495 }
496}
497
498impl Drop for Val {
499 fn drop(&mut self) {
500 unsafe { emlite_val_dec_ref(self.as_handle()) }
501 }
502}
503
504impl Clone for Val {
505 fn clone(&self) -> Val {
506 unsafe {
507 emlite_val_inc_ref(self.as_handle());
508 }
509 Val::take_ownership(self.as_handle())
510 }
511}
512
513use core::ops::{Deref, DerefMut};
514
515#[derive(Clone, Debug)]
517pub struct Console {
518 val: Val,
519}
520
521impl Console {
522 pub const fn get() -> Console {
524 Console {
525 val: Val {
526 inner: EmlitePredefHandles::Console as _,
527 },
528 }
529 }
530
531 pub fn log(&self, args: &[Val]) {
533 self.val.call("log", args);
534 }
535
536 pub fn warn(&self, args: &[Val]) {
538 self.val.call("warn", args);
539 }
540
541 pub fn info(&self, args: &[Val]) {
543 self.val.call("info", args);
544 }
545
546 pub fn as_handle(&self) -> Handle {
548 self.val.as_handle()
549 }
550}
551
552impl Deref for Console {
553 type Target = Val;
554
555 fn deref(&self) -> &Self::Target {
556 &self.val
557 }
558}
559
560impl DerefMut for Console {
561 fn deref_mut(&mut self) -> &mut Self::Target {
562 &mut self.val
563 }
564}
565
566impl From<Console> for Val {
567 fn from(val: Console) -> Self {
568 Val::take_ownership(val.as_handle())
569 }
570}
571
572use core::cmp::Ordering;
573use core::ops::Not;
574
575impl PartialEq for Val {
576 fn eq(&self, other: &Val) -> bool {
577 unsafe { emlite_val_strictly_equals(self.as_handle(), other.as_handle()) }
578 }
579}
580
581impl PartialOrd for Val {
582 fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
583 unsafe {
584 if emlite_val_strictly_equals(self.as_handle(), other.as_handle()) {
585 Some(Ordering::Equal)
586 } else if emlite_val_gt(self.as_handle(), other.as_handle()) {
587 Some(Ordering::Greater)
588 } else if emlite_val_lt(self.as_handle(), other.as_handle()) {
589 Some(Ordering::Less)
590 } else {
591 None
592 }
593 }
594 }
595}
596
597impl Not for Val {
598 type Output = bool;
599
600 fn not(self) -> Self::Output {
601 unsafe { emlite_val_not(self.as_handle()) }
602 }
603}
604
605impl core::ops::Not for &Val {
606 type Output = bool;
607
608 fn not(self) -> Self::Output {
609 unsafe { emlite_val_not_unified(self.as_handle()) }
610 }
611}
612
613impl AsRef<Val> for Val {
614 #[inline]
615 fn as_ref(&self) -> &Val {
616 self
617 }
618}
619
620impl AsMut<Val> for Val {
621 #[inline]
622 fn as_mut(&mut self) -> &mut Val {
623 self
624 }
625}
626
627pub trait FromVal: Sized {
628 fn from_val(v: &Val) -> Self;
630 fn take_ownership(v: Handle) -> Self;
632 fn as_handle(&self) -> Handle;
634}
635
636impl FromVal for Val {
637 fn from_val(v: &Val) -> Self {
638 unsafe {
639 emlite_val_inc_ref(v.inner);
640 }
641 Val {
642 inner: v.as_handle(),
643 }
644 }
645 fn take_ownership(v: Handle) -> Self {
646 Val { inner: v }
647 }
648 #[inline(always)]
649 fn as_handle(&self) -> Handle {
650 self.inner
651 }
652}
653
654impl FromVal for Result<Val, Val> {
655 fn from_val(v: &Val) -> Self {
656 unsafe {
657 emlite_val_inc_ref(v.inner);
658 }
659 if v.is_error() {
660 Err(v.clone())
661 } else {
662 Ok(v.clone())
663 }
664 }
665 fn take_ownership(v: Handle) -> Self {
666 let temp = Val::take_ownership(v);
667 if temp.is_error() { Err(temp) } else { Ok(temp) }
668 }
669 #[inline(always)]
670 fn as_handle(&self) -> Handle {
671 match self {
672 Ok(ok) => ok.as_handle(),
673 Err(e) => e.as_handle(),
674 }
675 }
676}
677
678impl FromVal for bool {
679 fn from_val(v: &Val) -> Self {
680 unsafe { !emlite_val_not_unified(v.as_handle()) }
681 }
682 fn take_ownership(v: Handle) -> Self {
683 Self::from_val(&Val::take_ownership(v))
684 }
685 fn as_handle(&self) -> Handle {
686 if *self {
687 EmlitePredefHandles::True as u32
688 } else {
689 EmlitePredefHandles::False as u32
690 }
691 }
692}
693
694impl FromVal for Option<bool> {
695 fn from_val(v: &Val) -> Self {
696 unsafe {
697 if v.is_error() || v.is_null() || v.is_undefined() {
698 None
699 } else {
700 Some(!emlite_val_not_unified(v.as_handle()))
701 }
702 }
703 }
704 fn take_ownership(v: Handle) -> Self {
705 let temp = Val::take_ownership(v);
706 if temp.is_error() || temp.is_null() || temp.is_undefined() {
707 None
708 } else {
709 unsafe { Some(!emlite_val_not_unified(v)) }
710 }
711 }
712 fn as_handle(&self) -> Handle {
713 match self {
714 Some(ok) => {
715 if *ok {
716 EmlitePredefHandles::True as u32
717 } else {
718 EmlitePredefHandles::False as u32
719 }
720 }
721 None => EmlitePredefHandles::Undefined as u32,
722 }
723 }
724}
725
726impl FromVal for Result<bool, Val> {
727 fn from_val(v: &Val) -> Self {
728 unsafe {
729 if v.is_error() {
730 Err(v.clone())
731 } else {
732 Ok(!emlite_val_not_unified(v.as_handle()))
733 }
734 }
735 }
736 fn take_ownership(v: Handle) -> Self {
737 let temp = Val::take_ownership(v);
738 if temp.is_error() {
739 Err(temp)
740 } else {
741 unsafe { Ok(!emlite_val_not_unified(v)) }
742 }
743 }
744 fn as_handle(&self) -> Handle {
745 match self {
746 Ok(ok) => {
747 if *ok {
748 EmlitePredefHandles::True as u32
749 } else {
750 EmlitePredefHandles::False as u32
751 }
752 }
753 Err(e) => e.as_handle(),
754 }
755 }
756}
757
758macro_rules! impl_int {
759 ($($t:ty),*) => {$(
760 impl FromVal for $t {
761 fn from_val(v: &Val) -> Self {
762 unsafe {
763 emlite_val_get_value_int(v.as_handle()) as Self
764 }
765 }
766 fn take_ownership(v: Handle) -> Self {
767 unsafe { emlite_val_get_value_int(v) as Self }
768 }
769 fn as_handle(&self) -> Handle {
770 0
771 }
772 }
773 impl FromVal for Option<$t> {
774 fn from_val(v: &Val) -> Self {
775 unsafe {
776 if !v.is_number() {
777 None
778 } else {
779 Some(emlite_val_get_value_int(v.as_handle()) as $t)
780 }
781 }
782 }
783 fn take_ownership(v: Handle) -> Self {
784 let temp = Val::take_ownership(v);
785 if !temp.is_number() {
786 None
787 } else {
788 unsafe { Some(emlite_val_get_value_int(v) as $t) }
789 }
790 }
791 fn as_handle(&self) -> Handle {
792 0
793 }
794 }
795 impl FromVal for Result<$t, Val> {
796 fn from_val(v: &Val) -> Self {
797 unsafe {
798 if v.is_error() {
799 Err(v.clone())
800 } else {
801 Ok(emlite_val_get_value_int(v.as_handle()) as $t)
802 }
803 }
804 }
805 fn take_ownership(v: Handle) -> Self {
806 let temp = Val::take_ownership(v);
807 if temp.is_error() {
808 Err(temp)
809 } else {
810 unsafe { Ok(emlite_val_get_value_int(v) as $t) }
811 }
812 }
813 fn as_handle(&self) -> Handle {
814 0
815 }
816 }
817 )*}
818}
819
820macro_rules! impl_uint {
821 ($($t:ty),*) => {$(
822 impl FromVal for $t {
823 fn from_val(v: &Val) -> Self {
824 unsafe {
825 emlite_val_get_value_uint(v.as_handle()) as Self
826 }
827 }
828 fn take_ownership(v: Handle) -> Self {
829 unsafe { emlite_val_get_value_uint(v) as Self }
830 }
831 fn as_handle(&self) -> Handle {
832 0
833 }
834 }
835 impl FromVal for Option<$t> {
836 fn from_val(v: &Val) -> Self {
837 unsafe {
838 if !v.is_number() {
839 None
840 } else {
841 Some(emlite_val_get_value_uint(v.as_handle()) as $t)
842 }
843 }
844 }
845 fn take_ownership(v: Handle) -> Self {
846 let temp = Val::take_ownership(v);
847 if !temp.is_number() {
848 None
849 } else {
850 unsafe { Some(emlite_val_get_value_uint(v) as $t) }
851 }
852 }
853 fn as_handle(&self) -> Handle {
854 0
855 }
856 }
857 impl FromVal for Result<$t, Val> {
858 fn from_val(v: &Val) -> Self {
859 unsafe {
860 if v.is_error() {
861 Err(v.clone())
862 } else {
863 Ok(emlite_val_get_value_uint(v.as_handle()) as $t)
864 }
865 }
866 }
867 fn take_ownership(v: Handle) -> Self {
868 let temp = Val::take_ownership(v);
869 if temp.is_error() {
870 Err(temp)
871 } else {
872 unsafe { Ok(emlite_val_get_value_uint(v) as $t) }
873 }
874 }
875 fn as_handle(&self) -> Handle {
876 0
877 }
878 }
879 )*}
880}
881
882macro_rules! impl_bigint {
883 ($($t:ty),*) => {$(
884 impl FromVal for $t {
885 fn from_val(v: &Val) -> Self {
886 unsafe {
887 emlite_val_get_value_bigint(v.as_handle()) as Self
888 }
889 }
890 fn take_ownership(v: Handle) -> Self {
891 unsafe { emlite_val_get_value_bigint(v) as Self }
892 }
893 fn as_handle(&self) -> Handle {
894 0
895 }
896 }
897 impl FromVal for Option<$t> {
898 fn from_val(v: &Val) -> Self {
899 unsafe {
900 if !v.is_number() {
901 None
902 } else {
903 Some(emlite_val_get_value_bigint(v.as_handle()) as $t)
904 }
905 }
906 }
907 fn take_ownership(v: Handle) -> Self {
908 let temp = Val::take_ownership(v);
909 if !temp.is_number() {
910 None
911 } else {
912 unsafe { Some(emlite_val_get_value_bigint(v) as $t) }
913 }
914 }
915 fn as_handle(&self) -> Handle {
916 0
917 }
918 }
919 impl FromVal for Result<$t, Val> {
920 fn from_val(v: &Val) -> Self {
921 unsafe {
922 if v.is_error() {
923 Err(v.clone())
924 } else {
925 Ok(emlite_val_get_value_bigint(v.as_handle()) as $t)
926 }
927 }
928 }
929 fn take_ownership(v: Handle) -> Self {
930 let temp = Val::take_ownership(v);
931 if temp.is_error() {
932 Err(temp)
933 } else {
934 unsafe { Ok(emlite_val_get_value_bigint(v) as $t) }
935 }
936 }
937 fn as_handle(&self) -> Handle {
938 0
939 }
940 }
941 )*}
942}
943
944macro_rules! impl_biguint {
945 ($($t:ty),*) => {$(
946 impl FromVal for $t {
947 fn from_val(v: &Val) -> Self {
948 unsafe {
949 emlite_val_get_value_biguint(v.as_handle()) as Self
950 }
951 }
952 fn take_ownership(v: Handle) -> Self {
953 unsafe { emlite_val_get_value_biguint(v) as Self }
954 }
955 fn as_handle(&self) -> Handle {
956 0
957 }
958 }
959 impl FromVal for Option<$t> {
960 fn from_val(v: &Val) -> Self {
961 unsafe {
962 if !v.is_number() {
963 None
964 } else {
965 Some(emlite_val_get_value_biguint(v.as_handle()) as $t)
966 }
967 }
968 }
969 fn take_ownership(v: Handle) -> Self {
970 let temp = Val::take_ownership(v);
971 if !temp.is_number() {
972 None
973 } else {
974 unsafe { Some(emlite_val_get_value_biguint(v) as $t) }
975 }
976 }
977 fn as_handle(&self) -> Handle {
978 0
979 }
980 }
981 impl FromVal for Result<$t, Val> {
982 fn from_val(v: &Val) -> Self {
983 unsafe {
984 if v.is_error() {
985 Err(v.clone())
986 } else {
987 Ok(emlite_val_get_value_biguint(v.as_handle()) as $t)
988 }
989 }
990 }
991 fn take_ownership(v: Handle) -> Self {
992 let temp = Val::take_ownership(v);
993 if temp.is_error() {
994 Err(temp)
995 } else {
996 unsafe { Ok(emlite_val_get_value_biguint(v) as $t) }
997 }
998 }
999 fn as_handle(&self) -> Handle {
1000 0
1001 }
1002 }
1003 )*}
1004}
1005
1006impl_int!(i8, i16, i32);
1007impl_uint!(u8, u16, u32);
1008impl_bigint!(i64, isize);
1009impl_biguint!(u64, usize);
1010
1011macro_rules! impl_float {
1012 ($($t:ty),*) => {$(
1013 impl FromVal for $t {
1014 fn from_val(v: &Val) -> Self {
1015 unsafe { emlite_val_get_value_double(v.as_handle()) as Self }
1016 }
1017 fn take_ownership(v: Handle) -> Self {
1018 unsafe { emlite_val_get_value_double(v) as Self }
1019 }
1020 fn as_handle(&self) -> Handle {
1021 0
1022 }
1023 }
1024 impl FromVal for Option<$t> {
1025 fn from_val(v: &Val) -> Self {
1026 unsafe {
1027 if !v.is_number() {
1028 None
1029 } else {
1030 Some(emlite_val_get_value_double(v.as_handle()) as $t)
1031 }
1032 }
1033 }
1034 fn take_ownership(v: Handle) -> Self {
1035 let temp = Val::take_ownership(v);
1036 if !temp.is_number() {
1037 None
1038 } else {
1039 unsafe { Some(emlite_val_get_value_double(v) as $t) }
1040 }
1041 }
1042 fn as_handle(&self) -> Handle {
1043 0
1044 }
1045 }
1046 impl FromVal for Result<$t, Val> {
1047 fn from_val(v: &Val) -> Self {
1048 unsafe {
1049 if v.is_error() {
1050 Err(v.clone())
1051 } else {
1052 Ok(emlite_val_get_value_double(v.as_handle()) as $t)
1053 }
1054 }
1055 }
1056 fn take_ownership(v: Handle) -> Self {
1057 let temp = Val::take_ownership(v);
1058 if temp.is_error() {
1059 Err(temp)
1060 } else {
1061 unsafe { Ok(emlite_val_get_value_double(v) as $t) }
1062 }
1063 }
1064 fn as_handle(&self) -> Handle {
1065 0
1066 }
1067 }
1068 )*}
1069}
1070
1071impl_float!(f32, f64);
1072
1073impl FromVal for () {
1074 fn from_val(_v: &Val) -> Self {}
1075 fn take_ownership(_v: Handle) -> Self {}
1076 fn as_handle(&self) -> Handle {
1077 EmlitePredefHandles::Undefined as u32
1078 }
1079}
1080
1081impl FromVal for Option<String> {
1082 fn from_val(v: &Val) -> Self {
1083 unsafe {
1084 if !v.is_string() {
1085 return None;
1086 }
1087 emlite_val_get_value_string_unified(v.as_handle())
1088 }
1089 }
1090 fn take_ownership(v: Handle) -> Self {
1091 unsafe {
1092 if !emlite_val_is_string(v) {
1093 return None;
1094 }
1095 emlite_val_get_value_string_unified(v)
1096 }
1097 }
1098 fn as_handle(&self) -> Handle {
1099 0
1100 }
1101}
1102
1103impl FromVal for Result<String, Val> {
1104 fn from_val(v: &Val) -> Self {
1105 unsafe {
1106 if v.is_error() {
1107 Err(v.clone())
1108 } else if !v.is_string() {
1109 Err(Val::global("Error").new(&["Expected string".into()]))
1110 } else {
1111 match emlite_val_get_value_string_unified(v.as_handle()) {
1112 Some(s) => Ok(s),
1113 None => Err(Val::global("Error").new(&["Null string".into()])),
1114 }
1115 }
1116 }
1117 }
1118 fn take_ownership(v: Handle) -> Self {
1119 unsafe {
1120 let temp = Val::take_ownership(v);
1121 if temp.is_error() {
1122 Err(temp)
1123 } else if !temp.is_string() {
1124 Err(Val::global("Error").new(&["Expected string".into()]))
1125 } else {
1126 match emlite_val_get_value_string_unified(v) {
1127 Some(s) => Ok(s),
1128 None => Err(Val::global("Error").new(&["Null string".into()])),
1129 }
1130 }
1131 }
1132 }
1133 fn as_handle(&self) -> Handle {
1134 0
1135 }
1136}
1137
1138impl FromVal for Option<Vec<u16>> {
1139 fn from_val(v: &Val) -> Self {
1140 unsafe { emlite_val_get_value_string_utf16_unified(v.as_handle()) }
1141 }
1142 fn take_ownership(v: Handle) -> Self {
1143 unsafe { emlite_val_get_value_string_utf16_unified(v) }
1144 }
1145 fn as_handle(&self) -> Handle {
1146 0
1147 }
1148}
1149
1150impl FromVal for Result<Vec<u16>, Val> {
1151 fn from_val(v: &Val) -> Self {
1152 unsafe {
1153 if v.is_error() {
1154 Err(v.clone())
1155 } else {
1156 match emlite_val_get_value_string_utf16_unified(v.as_handle()) {
1157 Some(vec) => Ok(vec),
1158 None => Err(Val::global("Error").new(&["Null UTF-16 string".into()])),
1159 }
1160 }
1161 }
1162 }
1163 fn take_ownership(v: Handle) -> Self {
1164 unsafe {
1165 let temp = Val::take_ownership(v);
1166 if temp.is_error() {
1167 Err(temp)
1168 } else {
1169 match emlite_val_get_value_string_utf16_unified(v) {
1170 Some(vec) => Ok(vec),
1171 None => Err(Val::global("Error").new(&["Null UTF-16 string".into()])),
1172 }
1173 }
1174 }
1175 }
1176 fn as_handle(&self) -> Handle {
1177 0
1178 }
1179}
1180
1181pub trait FromJsError {
1184 fn from_js_error(val: &Val) -> Self;
1185}
1186
1187impl<T, E> FromVal for Result<T, E>
1190where
1191 T: FromVal,
1192 E: FromJsError,
1193{
1194 fn from_val(v: &Val) -> Self {
1195 if v.is_error() {
1196 Err(E::from_js_error(v))
1197 } else {
1198 Ok(T::from_val(v))
1199 }
1200 }
1201 fn take_ownership(handle: Handle) -> Self {
1202 let temp = Val::take_ownership(handle);
1203 if temp.is_error() {
1204 Err(E::from_js_error(&temp))
1205 } else {
1206 Ok(T::take_ownership(handle))
1207 }
1208 }
1209 fn as_handle(&self) -> Handle {
1210 match self {
1211 Ok(ok) => ok.as_handle(),
1212 Err(_) => 0, }
1214 }
1215}