1pub use emlite::Console;
2pub use emlite::FromVal;
3
4pub use crate::any::{Any, AnyHandle};
5pub use crate::array::{
6 Array, ArrayBuffer, DataView, Endian, Float32Array, Float64Array, FrozenArray, Int8Array,
7 Int32Array, ObservableArray, TypedArray, Uint8Array, Uint32Array,
8};
9pub use crate::date::Date;
10pub use crate::error::*;
11pub use crate::function::{Closure, Function};
12pub use crate::json::JSON;
13pub use crate::map::*;
14pub use crate::math::Math;
15pub use crate::null::Null;
16pub use crate::object::Object;
17pub use crate::promise::Promise;
18pub use crate::record::Record;
19pub use crate::reflect::Reflect;
20pub use crate::response::{fetch, fetch_val};
21pub use crate::sequence::Sequence;
22pub use crate::set::*;
23pub use crate::string::{ByteString, CSSOMString, DOMString, USVString};
24pub use crate::text::{TextDecoder, TextEncoder};
25pub use crate::time::*;
26pub use crate::undefined::Undefined;
27pub use crate::url::URL;
28
29pub fn parse_int(src: &str, radix: Option<i32>) -> i32 {
31 let g = emlite::Val::global("parseInt");
32 match radix {
33 Some(r) => g.invoke(&[src.into(), r.into()]).as_::<i32>(),
34 None => g.invoke(&[src.into()]).as_::<i32>(),
35 }
36}
37
38pub fn parse_float(src: &str) -> f64 {
40 emlite::Val::global("parseFloat")
41 .invoke(&[src.into()])
42 .as_::<f64>()
43}
44
45pub trait DynCast
51where
52 Self: AsRef<emlite::Val> + Into<emlite::Val>,
53{
54 fn has_type<T>(&self) -> bool
55 where
56 T: DynCast,
57 {
58 T::is_type_of(self.as_ref())
59 }
60
61 fn dyn_into<T>(self) -> Result<T, Self>
62 where
63 T: DynCast,
64 {
65 if self.has_type::<T>() {
66 Ok(self.unchecked_into())
67 } else {
68 Err(self)
69 }
70 }
71
72 fn dyn_ref<T>(&self) -> Option<&T>
73 where
74 T: DynCast,
75 {
76 if self.has_type::<T>() {
77 Some(self.unchecked_ref())
78 } else {
79 None
80 }
81 }
82
83 fn unchecked_into<T>(self) -> T
84 where
85 T: DynCast,
86 {
87 T::unchecked_from_val(self.into())
88 }
89
90 fn unchecked_ref<T>(&self) -> &T
91 where
92 T: DynCast,
93 {
94 T::unchecked_from_val_ref(self.as_ref())
95 }
96
97 fn is_instance_of<T>(&self) -> bool
98 where
99 T: DynCast,
100 {
101 T::instanceof(self.as_ref())
102 }
103
104 fn instanceof(val: &emlite::Val) -> bool;
106
107 fn is_type_of(val: &emlite::Val) -> bool {
109 Self::instanceof(val)
110 }
111
112 fn unchecked_from_val(v: emlite::Val) -> Self;
114
115 fn unchecked_from_val_ref(v: &emlite::Val) -> &Self;
117}
118
119#[cold]
121#[inline(never)]
122pub fn throw_str(s: &str) -> ! {
123 throw_val(s.into())
124}
125
126#[cold]
128#[inline(never)]
129pub fn throw_val(s: Any) -> ! {
130 unsafe {
131 let handle = s.as_handle();
132 core::mem::forget(s);
133 emlite::env::emlite_val_throw(handle)
134 }
135}
136
137pub trait UnwrapThrowExt<T>: Sized {
139 fn unwrap_throw(self) -> T {
140 let loc = core::panic::Location::caller();
141 let msg = alloc::format!(
142 "called `{}::unwrap_throw()` ({}:{}:{})",
143 core::any::type_name::<Self>(),
144 loc.file(),
145 loc.line(),
146 loc.column()
147 );
148 self.expect_throw(&msg)
149 }
150
151 fn expect_throw(self, message: &str) -> T;
152}
153
154impl<T> UnwrapThrowExt<T> for Option<T> {
156 fn unwrap_throw(self) -> T {
157 const MSG: &str = "called `Option::unwrap_throw()` on a `None` value";
158 if let Some(val) = self {
159 val
160 } else if cfg!(debug_assertions) {
161 let loc = core::panic::Location::caller();
162 let msg = alloc::format!("{} ({}:{}:{})", MSG, loc.file(), loc.line(), loc.column(),);
163
164 throw_str(&msg)
165 } else {
166 throw_str(MSG)
167 }
168 }
169
170 fn expect_throw(self, message: &str) -> T {
171 if let Some(val) = self {
172 val
173 } else if cfg!(debug_assertions) {
174 let loc = core::panic::Location::caller();
175 let msg = alloc::format!(
176 "{} ({}:{}:{})",
177 message,
178 loc.file(),
179 loc.line(),
180 loc.column(),
181 );
182
183 throw_str(&msg)
184 } else {
185 throw_str(message)
186 }
187 }
188}
189
190impl<T, E> UnwrapThrowExt<T> for Result<T, E>
192where
193 E: core::fmt::Debug,
194{
195 fn unwrap_throw(self) -> T {
196 const MSG: &str = "called `Result::unwrap_throw()` on an `Err` value";
197 match self {
198 Ok(val) => val,
199 Err(err) => {
200 if cfg!(debug_assertions) {
201 let loc = core::panic::Location::caller();
202 let msg = alloc::format!(
203 "{} ({}:{}:{}): {:?}",
204 MSG,
205 loc.file(),
206 loc.line(),
207 loc.column(),
208 err
209 );
210
211 throw_str(&msg)
212 } else {
213 throw_str(MSG)
214 }
215 }
216 }
217 }
218
219 fn expect_throw(self, message: &str) -> T {
220 match self {
221 Ok(val) => val,
222 Err(err) => {
223 if cfg!(debug_assertions) {
224 let loc = core::panic::Location::caller();
225 let msg = alloc::format!(
226 "{} ({}:{}:{}): {:?}",
227 message,
228 loc.file(),
229 loc.line(),
230 loc.column(),
231 err
232 );
233
234 throw_str(&msg)
235 } else {
236 throw_str(message)
237 }
238 }
239 }
240 }
241}