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 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 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 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 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
75pub struct Invocation {
78 pub mv8: MiniV8,
80 pub this: Value,
82 pub args: Values,
84}