Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seal Filter/Test/Function #113

Merged
merged 1 commit into from Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,8 @@ All notable changes to MiniJinja are documented here.
- Added custom formatters.
- Restructured engine internals for greater clarity.
- Added support for rendering to `io::Write`. (#111)
- Make it impossible to implement `Fitler`, `Test`
or `Function` from outside the crate (sealed the traits).

# 0.20.0

Expand Down
6 changes: 4 additions & 2 deletions minijinja/src/filters.rs
Expand Up @@ -60,6 +60,7 @@ use std::sync::Arc;
use crate::defaults::escape_formatter;
use crate::error::Error;
use crate::output::Output;
use crate::utils::SealedMarker;
use crate::value::{ArgType, FunctionArgs, FunctionResult, Value};
use crate::vm::State;
use crate::AutoEscape;
Expand Down Expand Up @@ -103,7 +104,7 @@ pub(crate) struct BoxedFilter(Arc<FilterFunc>);
pub trait Filter<V, Rv, Args>: Send + Sync + 'static {
/// Applies a filter to value with the given arguments.
#[doc(hidden)]
fn apply_to(&self, state: &State, value: V, args: Args) -> Rv;
fn apply_to(&self, state: &State, value: V, args: Args, _: SealedMarker) -> Rv;
}

macro_rules! tuple_impls {
Expand All @@ -115,7 +116,7 @@ macro_rules! tuple_impls {
Rv: FunctionResult,
$($name: for<'a> ArgType<'a>),*
{
fn apply_to(&self, state: &State, value: V, args: ($($name,)*)) -> Rv {
fn apply_to(&self, state: &State, value: V, args: ($($name,)*), _: SealedMarker) -> Rv {
#[allow(non_snake_case)]
let ($($name,)*) = args;
(self)(state, value, $($name,)*)
Expand Down Expand Up @@ -145,6 +146,7 @@ impl BoxedFilter {
state,
ArgType::from_value(Some(value))?,
FunctionArgs::from_values(args)?,
SealedMarker,
)
.into_result()
},
Expand Down
7 changes: 4 additions & 3 deletions minijinja/src/functions.rs
Expand Up @@ -52,6 +52,7 @@ use std::fmt;
use std::sync::Arc;

use crate::error::Error;
use crate::utils::SealedMarker;
use crate::value::{ArgType, FunctionArgs, FunctionResult, Object, Value};
use crate::vm::State;

Expand Down Expand Up @@ -98,7 +99,7 @@ pub(crate) struct BoxedFunction(Arc<FuncFunc>, &'static str);
pub trait Function<Rv, Args>: Send + Sync + 'static {
/// Calls a function with the given arguments.
#[doc(hidden)]
fn invoke(&self, env: &State, args: Args) -> Rv;
fn invoke(&self, env: &State, args: Args, _: SealedMarker) -> Rv;
}

macro_rules! tuple_impls {
Expand All @@ -109,7 +110,7 @@ macro_rules! tuple_impls {
Rv: FunctionResult,
$($name: for<'a> ArgType<'a>),*
{
fn invoke(&self, state: &State, args: ($($name,)*)) -> Rv {
fn invoke(&self, state: &State, args: ($($name,)*), _: SealedMarker) -> Rv {
#[allow(non_snake_case)]
let ($($name,)*) = args;
(self)(state, $($name,)*)
Expand All @@ -134,7 +135,7 @@ impl BoxedFunction {
{
BoxedFunction(
Arc::new(move |env, args| -> Result<Value, Error> {
f.invoke(env, FunctionArgs::from_values(args)?)
f.invoke(env, FunctionArgs::from_values(args)?, SealedMarker)
.into_result()
}),
std::any::type_name::<F>(),
Expand Down
6 changes: 4 additions & 2 deletions minijinja/src/tests.rs
Expand Up @@ -58,6 +58,7 @@
use std::sync::Arc;

use crate::error::Error;
use crate::utils::SealedMarker;
use crate::value::{ArgType, FunctionArgs, Value};
use crate::vm::State;

Expand Down Expand Up @@ -126,7 +127,7 @@ impl TestResult for bool {
pub trait Test<V, Rv, Args>: Send + Sync + 'static {
/// Performs a test to value with the given arguments.
#[doc(hidden)]
fn perform(&self, state: &State, value: V, args: Args) -> Rv;
fn perform(&self, state: &State, value: V, args: Args, _: SealedMarker) -> Rv;
}

macro_rules! tuple_impls {
Expand All @@ -138,7 +139,7 @@ macro_rules! tuple_impls {
Rv: TestResult,
$($name: for<'a> ArgType<'a>),*
{
fn perform(&self, state: &State, value: V, args: ($($name,)*)) -> Rv {
fn perform(&self, state: &State, value: V, args: ($($name,)*), _: SealedMarker) -> Rv {
#[allow(non_snake_case)]
let ($($name,)*) = args;
(self)(state, value, $($name,)*)
Expand Down Expand Up @@ -168,6 +169,7 @@ impl BoxedTest {
state,
ArgType::from_value(value)?,
FunctionArgs::from_values(args)?,
SealedMarker,
)
.into_result()
}))
Expand Down
3 changes: 3 additions & 0 deletions minijinja/src/utils.rs
Expand Up @@ -9,6 +9,9 @@ use crate::error::{Error, ErrorKind};
#[cfg(test)]
use similar_asserts::assert_eq;

/// internal marker to seal up some trait methods
pub struct SealedMarker;

pub fn memchr(haystack: &[u8], needle: u8) -> Option<usize> {
haystack.iter().position(|&x| x == needle)
}
Expand Down