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