mini_v8/
function.rs

1use crate::*;
2use std::fmt;
3
4#[derive(Clone)]
5pub struct Function {
6    pub(crate) mv8: MiniV8,
7    pub(crate) handle: v8::Global<v8::Function>,
8}
9
10impl Function {
11    /// Consumes the function and downgrades it to a JavaScript object.
12    pub fn into_object(self) -> Object {
13        self.mv8.clone().scope(|scope| {
14            let object: v8::Local<v8::Object> = v8::Local::new(scope, self.handle.clone()).into();
15            Object {
16                mv8: self.mv8,
17                handle: v8::Global::new(scope, object),
18            }
19        })
20    }
21
22    /// Calls the function with the given arguments, with `this` set to `undefined`.
23    pub fn call<A, R>(&self, args: A) -> Result<R>
24    where
25        A: ToValues,
26        R: FromValue,
27    {
28        self.call_method(Value::Undefined, args)
29    }
30
31    /// Calls the function with the given `this` and arguments.
32    pub fn call_method<T, A, R>(&self, this: T, args: A) -> Result<R>
33    where
34        T: ToValue,
35        A: ToValues,
36        R: FromValue,
37    {
38        let this = this.to_value(&self.mv8)?;
39        let args = args.to_values(&self.mv8)?;
40        self.mv8.try_catch(|scope| {
41            let function = v8::Local::new(scope, self.handle.clone());
42            let this = this.to_v8_value(scope);
43            let args = args.into_vec();
44            let args_v8: Vec<_> = args.into_iter().map(|v| v.to_v8_value(scope)).collect();
45            let result = function.call(scope, this, &args_v8);
46            self.mv8.exception(scope)?;
47            Ok(Value::from_v8_value(&self.mv8, scope, result.unwrap()))
48        }).and_then(|v| v.into(&self.mv8))
49    }
50
51    /// Calls the function as a constructor function with the given arguments.
52    pub fn call_new<A, R>(&self, args: A) -> Result<R>
53    where
54        A: ToValues,
55        R: FromValue,
56    {
57        let args = args.to_values(&self.mv8)?;
58        self.mv8.try_catch(|scope| {
59            let function = v8::Local::new(scope, self.handle.clone());
60            let args = args.into_vec();
61            let args_v8: Vec<_> = args.into_iter().map(|v| v.to_v8_value(scope)).collect();
62            let result = function.new_instance(scope, &args_v8);
63            self.mv8.exception(scope)?;
64            Ok(Value::from_v8_value(&self.mv8, scope, result.unwrap().into()))
65        }).and_then(|v| v.into(&self.mv8))
66    }
67}
68
69impl fmt::Debug for Function {
70    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71        write!(f, "<function>")
72    }
73}
74
75/// A bundle of information about an invocation of a function that has been embedded from Rust into
76/// JavaScript.
77pub struct Invocation {
78    /// The `MiniV8` within which the function was called.
79    pub mv8: MiniV8,
80    /// The value of the function invocation's `this` binding.
81    pub this: Value,
82    /// The list of arguments with which the function was called.
83    pub args: Values,
84}