Skip to main content

simple_expressions/types/
function.rs

1use crate::types::coerce::Context;
2use crate::types::error::{Error, Result};
3use crate::types::object::Object;
4use crate::types::value::Value;
5use std::any::Any;
6use std::rc::Rc;
7
8pub type Callable = Rc<dyn Fn(&[Value], &Context) -> Result<Value>>;
9
10pub fn new(callable: Callable) -> Value {
11    Value::Object(Rc::new(Function::new(callable)))
12}
13
14pub struct Function {
15    callable: Callable,
16}
17
18impl Function {
19    pub fn new(callable: Callable) -> Self {
20        Self { callable }
21    }
22}
23
24impl Object for Function {
25    fn type_name(&self) -> &'static str {
26        "function"
27    }
28
29    fn call(&self, args: &[Value], cx: &Context) -> Result<Value> {
30        self.callable.as_ref()(args, cx)
31    }
32
33    fn as_any(&self) -> &dyn Any {
34        self
35    }
36
37    fn as_any_mut(&mut self) -> &mut dyn Any {
38        self
39    }
40}
41
42/// A function taking no arguments.
43pub fn method0<F>(f: F) -> Value
44where
45    F: Fn(&Context) -> Result<Value> + 'static,
46{
47    new(Rc::new(move |args: &[Value], cx: &Context| {
48        if !args.is_empty() {
49            return Err(Error::EvaluationFailed("expected 0 args".into()));
50        }
51        f(cx)
52    }))
53}
54
55/// A function taking one expression-language argument.
56pub fn method1<F>(f: F) -> Value
57where
58    F: Fn(&Value, &Context) -> Result<Value> + 'static,
59{
60    new(Rc::new(move |args: &[Value], cx: &Context| {
61        if args.len() != 1 {
62            return Err(Error::EvaluationFailed("expected 1 arg".into()));
63        }
64        f(&args[0], cx)
65    }))
66}