Skip to content

Commit

Permalink
New Function Traits (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Sep 3, 2022
1 parent c195120 commit 981a8bb
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 103 deletions.
4 changes: 2 additions & 2 deletions examples/dynamic/src/main.rs
Expand Up @@ -18,7 +18,7 @@ impl fmt::Display for Cycler {
}

impl Object for Cycler {
fn call(&self, _state: &State, args: Vec<Value>) -> Result<Value, Error> {
fn call(&self, _state: &State, args: &[Value]) -> Result<Value, Error> {
let _: () = FunctionArgs::from_values(args)?;
let idx = self.idx.fetch_add(1, Ordering::Relaxed);
Ok(self.values[idx % self.values.len()].clone())
Expand All @@ -42,7 +42,7 @@ impl fmt::Display for Magic {
}

impl Object for Magic {
fn call_method(&self, _state: &State, name: &str, args: Vec<Value>) -> Result<Value, Error> {
fn call_method(&self, _state: &State, name: &str, args: &[Value]) -> Result<Value, Error> {
if name == "make_class" {
let (tag,): (String,) = FunctionArgs::from_values(args)?;
Ok(Value::from(format!("magic-{}", tag)))
Expand Down
10 changes: 5 additions & 5 deletions minijinja/src/environment.rs
Expand Up @@ -526,10 +526,10 @@ impl<'source> Environment<'source> {
/// For details about filters have a look at [`filters`].
pub fn add_filter<F, V, Rv, Args>(&mut self, name: &'source str, f: F)
where
V: ArgType,
V: for<'a> ArgType<'a>,
Rv: Into<Value>,
F: filters::Filter<V, Rv, Args>,
Args: FunctionArgs,
Args: for<'a> FunctionArgs<'a>,
{
self.filters.insert(name, filters::BoxedFilter::new(f));
}
Expand All @@ -544,9 +544,9 @@ impl<'source> Environment<'source> {
/// For details about tests have a look at [`tests`].
pub fn add_test<F, V, Args>(&mut self, name: &'source str, f: F)
where
V: ArgType,
V: for<'a> ArgType<'a>,
F: tests::Test<V, Args>,
Args: FunctionArgs,
Args: for<'a> FunctionArgs<'a>,
{
self.tests.insert(name, tests::BoxedTest::new(f));
}
Expand All @@ -564,7 +564,7 @@ impl<'source> Environment<'source> {
where
Rv: Into<Value>,
F: functions::Function<Rv, Args>,
Args: FunctionArgs,
Args: for<'a> FunctionArgs<'a>,
{
self.add_global(name, functions::BoxedFunction::new(f).to_value());
}
Expand Down
20 changes: 10 additions & 10 deletions minijinja/src/filters.rs
Expand Up @@ -51,7 +51,7 @@ use crate::value::{ArgType, FunctionArgs, RcType, Value};
use crate::vm::State;
use crate::AutoEscape;

type FilterFunc = dyn Fn(&State, Value, Vec<Value>) -> Result<Value, Error> + Sync + Send + 'static;
type FilterFunc = dyn Fn(&State, &Value, &[Value]) -> Result<Value, Error> + Sync + Send + 'static;

#[derive(Clone)]
pub(crate) struct BoxedFilter(RcType<FilterFunc>);
Expand Down Expand Up @@ -89,9 +89,9 @@ impl BoxedFilter {
pub fn new<F, V, Rv, Args>(f: F) -> BoxedFilter
where
F: Filter<V, Rv, Args>,
V: ArgType,
V: for<'a> ArgType<'a>,
Rv: Into<Value>,
Args: FunctionArgs,
Args: for<'a> FunctionArgs<'a>,
{
BoxedFilter(RcType::new(
move |state, value, args| -> Result<Value, Error> {
Expand All @@ -106,7 +106,7 @@ impl BoxedFilter {
}

/// Applies the filter to a value and argument.
pub fn apply_to(&self, state: &State, value: Value, args: Vec<Value>) -> Result<Value, Error> {
pub fn apply_to(&self, state: &State, value: &Value, args: &[Value]) -> Result<Value, Error> {
(self.0)(state, value, args)
}
}
Expand Down Expand Up @@ -759,7 +759,7 @@ mod builtins {
};
let bx = BoxedFilter::new(test);
assert_eq!(
bx.apply_to(&state, Value::from(23), vec![Value::from(42)])
bx.apply_to(&state, &Value::from(23), &[Value::from(42)][..])
.unwrap(),
Value::from(65)
);
Expand All @@ -785,24 +785,24 @@ mod builtins {
};
let bx = BoxedFilter::new(add);
assert_eq!(
bx.apply_to(&state, Value::from(23), vec![Value::from(42)])
bx.apply_to(&state, &Value::from(23), &[Value::from(42)][..])
.unwrap(),
Value::from(65)
);
assert_eq!(
bx.apply_to(
&state,
Value::from(23),
vec![Value::from(42), Value::UNDEFINED]
&Value::from(23),
&[Value::from(42), Value::UNDEFINED][..]
)
.unwrap(),
Value::from(65)
);
assert_eq!(
bx.apply_to(
&state,
Value::from(23),
vec![Value::from(42), Value::from(1)]
&Value::from(23),
&[Value::from(42), Value::from(1)][..]
)
.unwrap(),
Value::from(66)
Expand Down
8 changes: 4 additions & 4 deletions minijinja/src/functions.rs
Expand Up @@ -46,7 +46,7 @@ use crate::error::Error;
use crate::value::{FunctionArgs, Object, Value};
use crate::vm::State;

type FuncFunc = dyn Fn(&State, Vec<Value>) -> Result<Value, Error> + Sync + Send + 'static;
type FuncFunc = dyn Fn(&State, &[Value]) -> Result<Value, Error> + Sync + Send + 'static;

/// A boxed function.
#[derive(Clone)]
Expand Down Expand Up @@ -86,7 +86,7 @@ impl BoxedFunction {
where
F: Function<Rv, Args>,
Rv: Into<Value>,
Args: FunctionArgs,
Args: for<'a> FunctionArgs<'a>,
{
BoxedFunction(
Arc::new(move |env, args| -> Result<Value, Error> {
Expand All @@ -98,7 +98,7 @@ impl BoxedFunction {
}

/// Invokes the function.
pub fn invoke(&self, state: &State, args: Vec<Value>) -> Result<Value, Error> {
pub fn invoke(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
(self.0)(state, args)
}

Expand Down Expand Up @@ -129,7 +129,7 @@ impl fmt::Display for BoxedFunction {
}

impl Object for BoxedFunction {
fn call(&self, state: &State, args: Vec<Value>) -> Result<Value, Error> {
fn call(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
self.invoke(state, args)
}
}
Expand Down
13 changes: 7 additions & 6 deletions minijinja/src/tests.rs
Expand Up @@ -51,7 +51,7 @@ use crate::error::Error;
use crate::value::{ArgType, FunctionArgs, RcType, Value};
use crate::vm::State;

type TestFunc = dyn Fn(&State, Value, Vec<Value>) -> Result<bool, Error> + Sync + Send + 'static;
type TestFunc = dyn Fn(&State, &Value, &[Value]) -> Result<bool, Error> + Sync + Send + 'static;

#[derive(Clone)]
pub(crate) struct BoxedTest(RcType<TestFunc>);
Expand Down Expand Up @@ -89,22 +89,23 @@ impl BoxedTest {
pub fn new<F, V, Args>(f: F) -> BoxedTest
where
F: Test<V, Args>,
V: ArgType,
Args: FunctionArgs,
V: for<'a> ArgType<'a>,
Args: for<'a> FunctionArgs<'a>,
{
BoxedTest(RcType::new(
move |state, value, args| -> Result<bool, Error> {
let value = Some(value);
f.perform(
state,
ArgType::from_value(Some(value))?,
ArgType::from_value(value)?,
FunctionArgs::from_values(args)?,
)
},
))
}

/// Applies the filter to a value and argument.
pub fn perform(&self, state: &State, value: Value, args: Vec<Value>) -> Result<bool, Error> {
pub fn perform(&self, state: &State, value: &Value, args: &[Value]) -> Result<bool, Error> {
(self.0)(state, value, args)
}
}
Expand Down Expand Up @@ -213,7 +214,7 @@ mod builtins {
};
let bx = BoxedTest::new(test);
assert!(bx
.perform(&state, Value::from(23), vec![Value::from(23)])
.perform(&state, &Value::from(23), &[Value::from(23)][..])
.unwrap());
}
}
Expand Down

0 comments on commit 981a8bb

Please sign in to comment.