1use std::any::Any;
8use std::mem::forget;
9use std::thread::Result;
10
11pub use arguments::{Accessor, Arguments, FromArgument};
12pub use closure::{Closure, ClosureOnce};
13pub use function::{Function, NativeFunction};
14use mozjs::conversions::ConversionBehavior;
15
16use crate::conversions::{FromValue, ToValue as _};
17use crate::{Context, Error, Object, ResultExc, ThrowException as _, Value};
18
19mod arguments;
20mod closure;
21mod function;
22
23#[doc(hidden)]
24pub fn __handle_native_function_result(cx: &Context, result: Result<ResultExc<()>>) -> bool {
25 match result {
26 Ok(Ok(_)) => true,
27 Ok(Err(error)) => {
28 error.throw(cx);
29 false
30 }
31 Err(unwind_error) => handle_unwind_error(cx, unwind_error),
32 }
33}
34
35#[doc(hidden)]
36pub fn __handle_native_constructor_result(
37 cx: &Context, result: Result<ResultExc<()>>, this: &Object, rval: &mut Value,
38) -> bool {
39 match result {
40 Ok(Ok(_)) => {
41 this.to_value(cx, rval);
42 true
43 }
44 Ok(Err(error)) => {
45 error.throw(cx);
46 false
47 }
48 Err(unwind_error) => handle_unwind_error(cx, unwind_error),
49 }
50}
51
52fn handle_unwind_error(cx: &Context, unwind_error: Box<dyn Any + Send>) -> bool {
53 match unwind_error.downcast::<String>() {
54 Ok(unwind) => Error::new(*unwind, None).throw(cx),
55 Err(unwind_error) => {
56 if let Some(unwind) = unwind_error.downcast_ref::<&'static str>() {
57 Error::new(*unwind, None).throw(cx);
58 } else {
59 Error::new("Unknown Panic Occurred", None).throw(cx);
60 forget(unwind_error);
61 }
62 }
63 }
64 false
65}
66
67pub struct Opt<T>(pub Option<T>);
69
70pub struct Rest<T>(pub Box<[T]>);
72
73pub type VarArgs<T> = Rest<T>;
74
75pub struct Strict<T>(pub T);
77
78impl<'cx, T: FromValue<'cx>> FromValue<'cx> for Strict<T> {
79 type Config = T::Config;
80
81 fn from_value(cx: &'cx Context, value: &Value, _: bool, config: Self::Config) -> crate::Result<Strict<T>> {
82 T::from_value(cx, value, true, config).map(Strict)
83 }
84}
85
86#[derive(Clone, Copy, Debug, Default)]
88pub struct Wrap<T>(pub T);
89
90impl<'cx, T: FromValue<'cx, Config = ConversionBehavior>> FromValue<'cx> for Wrap<T> {
91 type Config = ();
92
93 fn from_value(cx: &'cx Context, value: &Value, strict: bool, _: ()) -> crate::Result<Wrap<T>> {
94 T::from_value(cx, value, strict, ConversionBehavior::Default).map(Wrap)
95 }
96}
97
98#[derive(Clone, Copy, Debug, Default)]
100pub struct Enforce<T>(pub T);
101
102impl<'cx, T: FromValue<'cx, Config = ConversionBehavior>> FromValue<'cx> for Enforce<T> {
103 type Config = ();
104
105 fn from_value(cx: &'cx Context, value: &Value, strict: bool, _: ()) -> crate::Result<Enforce<T>> {
106 T::from_value(cx, value, strict, ConversionBehavior::EnforceRange).map(Enforce)
107 }
108}
109
110#[derive(Clone, Copy, Debug, Default)]
112pub struct Clamp<T>(pub T);
113
114impl<'cx, T: FromValue<'cx, Config = ConversionBehavior>> FromValue<'cx> for Clamp<T> {
115 type Config = ();
116
117 fn from_value(cx: &'cx Context, value: &Value, strict: bool, _: ()) -> crate::Result<Clamp<T>> {
118 T::from_value(cx, value, strict, ConversionBehavior::Clamp).map(Clamp)
119 }
120}