Skip to content

Commit 2a75327

Browse files
committed
Revert "implement Context-local functions and ergonomic wrappers marking functions as safe (#666)"
This reverts commit 34435db.
1 parent 74e9954 commit 2a75327

File tree

5 files changed

+9
-113
lines changed

5 files changed

+9
-113
lines changed

src/builtins/functions.rs

-57
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,6 @@ use serde_json::value::{from_value, to_value, Value};
88

99
use crate::errors::{Error, Result};
1010

11-
/// The context-local function type definition
12-
pub trait FunctionRelaxed {
13-
/// The context-local function type definition
14-
fn call(&self, args: &HashMap<String, Value>) -> Result<Value>;
15-
16-
/// Whether the current function's output should be treated as safe, defaults to `false`
17-
fn is_safe(&self) -> bool {
18-
false
19-
}
20-
}
21-
22-
impl<F> FunctionRelaxed for F
23-
where
24-
F: Fn(&HashMap<String, Value>) -> Result<Value>,
25-
{
26-
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> {
27-
self(args)
28-
}
29-
}
30-
3111
/// The global function type definition
3212
pub trait Function: Sync + Send {
3313
/// The global function type definition
@@ -48,43 +28,6 @@ where
4828
}
4929
}
5030

51-
macro_rules! safe_function {
52-
($function_trait:ident, $function_wrapper:ident) => {
53-
/// Wrapper to make `is_safe` return `true` instead of `false` for a trait implementation.
54-
pub struct $function_wrapper<F>
55-
where
56-
F: $function_trait,
57-
{
58-
inner: F,
59-
}
60-
61-
impl<F> $function_trait for $function_wrapper<F>
62-
where
63-
F: $function_trait,
64-
{
65-
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> {
66-
self.inner.call(args)
67-
}
68-
69-
fn is_safe(&self) -> bool {
70-
true
71-
}
72-
}
73-
74-
impl<F> From<F> for $function_wrapper<F>
75-
where
76-
F: $function_trait,
77-
{
78-
fn from(func: F) -> Self {
79-
$function_wrapper { inner: func }
80-
}
81-
}
82-
};
83-
}
84-
85-
safe_function!(FunctionRelaxed, FunctionRelaxedSafe);
86-
safe_function!(Function, FunctionSafe);
87-
8831
pub fn range(args: &HashMap<String, Value>) -> Result<Value> {
8932
let start = match args.get("start") {
9033
Some(val) => match from_value::<usize>(val.clone()) {

src/context.rs

+3-37
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,20 @@ use serde::ser::Serialize;
55
use serde_json::value::{to_value, Map, Value};
66

77
use crate::errors::{Error, Result as TeraResult};
8-
use crate::FunctionRelaxed;
9-
use std::sync::Arc;
108

119
/// The struct that holds the context of a template rendering.
1210
///
1311
/// Light wrapper around a `BTreeMap` for easier insertions of Serializable
1412
/// values
15-
#[derive(Clone)]
13+
#[derive(Debug, Clone, PartialEq)]
1614
pub struct Context {
1715
data: BTreeMap<String, Value>,
18-
/// Ignored by PartialEq!
19-
functions: BTreeMap<String, Arc<dyn FunctionRelaxed>>,
20-
}
21-
22-
impl std::fmt::Debug for Context {
23-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24-
f.debug_struct("Context")
25-
.field("data", &self.data)
26-
.field("functions", &self.functions.keys())
27-
.finish()
28-
}
29-
}
30-
31-
impl PartialEq for Context {
32-
fn eq(&self, other: &Self) -> bool {
33-
self.data.eq(&other.data)
34-
}
3516
}
3617

3718
impl Context {
3819
/// Initializes an empty context
3920
pub fn new() -> Self {
40-
Context { data: BTreeMap::new(), functions: Default::default() }
21+
Context { data: BTreeMap::new() }
4122
}
4223

4324
/// Converts the `val` parameter to `Value` and insert it into the context.
@@ -82,15 +63,6 @@ impl Context {
8263
Ok(())
8364
}
8465

85-
/// Registers Context-local function
86-
pub fn register_function<T: FunctionRelaxed + 'static, S: Into<String>>(
87-
&mut self,
88-
key: S,
89-
val: T,
90-
) {
91-
self.functions.insert(key.into(), Arc::new(val));
92-
}
93-
9466
/// Appends the data of the `source` parameter to `self`, overwriting existing keys.
9567
/// The source context will be dropped.
9668
///
@@ -125,7 +97,7 @@ impl Context {
12597
for (key, value) in m {
12698
data.insert(key, value);
12799
}
128-
Ok(Context { data, functions: Default::default() })
100+
Ok(Context { data })
129101
}
130102
_ => Err(Error::msg(
131103
"Creating a Context from a Value/Serialize requires it being a JSON object",
@@ -155,12 +127,6 @@ impl Context {
155127
pub fn contains_key(&self, index: &str) -> bool {
156128
self.data.contains_key(index)
157129
}
158-
159-
/// Looks up Context-local registered function
160-
#[inline]
161-
pub fn get_function(&self, fn_name: &str) -> Option<&Arc<dyn FunctionRelaxed>> {
162-
self.functions.get(fn_name)
163-
}
164130
}
165131

166132
impl Default for Context {

src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//! See the [site](https://tera.netlify.com) for features and to get started.
88
99
#![deny(missing_docs)]
10-
#![deny(warnings)]
1110

1211
#[macro_use]
1312
mod macros;
@@ -24,9 +23,7 @@ mod utils;
2423
// Library exports.
2524

2625
pub use crate::builtins::filters::Filter;
27-
pub use crate::builtins::functions::{
28-
Function, FunctionRelaxed, FunctionRelaxedSafe, FunctionSafe,
29-
};
26+
pub use crate::builtins::functions::Function;
3027
pub use crate::builtins::testers::Test;
3128
pub use crate::context::Context;
3229
pub use crate::errors::{Error, ErrorKind, Result};

src/renderer/call_stack.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use crate::errors::{Error, Result};
88
use crate::renderer::for_loop::{ForLoop, ForLoopState};
99
use crate::renderer::stack_frame::{FrameContext, FrameType, StackFrame, Val};
1010
use crate::template::Template;
11-
use crate::{Context, FunctionRelaxed};
12-
use std::sync::Arc;
11+
use crate::Context;
1312

1413
/// Contains the user data and allows no mutation
1514
#[derive(Debug)]
@@ -132,10 +131,6 @@ impl<'a> CallStack<'a> {
132131
None
133132
}
134133

135-
pub fn lookup_function(&self, fn_name: &str) -> Option<&Arc<dyn FunctionRelaxed>> {
136-
self.context.inner.get_function(fn_name)
137-
}
138-
139134
/// Add an assignment value (via {% set ... %} and {% set_global ... %} )
140135
pub fn add_assignment(&mut self, key: &'a str, global: bool, value: Val<'a>) {
141136
if global {

src/renderer/processor.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ impl<'a> Processor<'a> {
491491
function_call: &'a FunctionCall,
492492
needs_escape: &mut bool,
493493
) -> Result<Val<'a>> {
494+
let tera_fn = self.tera.get_function(&function_call.name)?;
495+
*needs_escape = !tera_fn.is_safe();
496+
494497
let err_wrap = |e| Error::call_function(&function_call.name, e);
495498

496499
let mut args = HashMap::new();
@@ -501,15 +504,7 @@ impl<'a> Processor<'a> {
501504
);
502505
}
503506

504-
if let Some(tera_fn) = self.call_stack.lookup_function(&function_call.name) {
505-
*needs_escape = !tera_fn.is_safe();
506-
Ok(Cow::Owned(tera_fn.call(&args).map_err(err_wrap)?))
507-
} else {
508-
let tera_fn = self.tera.get_function(&function_call.name)?;
509-
*needs_escape = !tera_fn.is_safe();
510-
511-
Ok(Cow::Owned(tera_fn.call(&args).map_err(err_wrap)?))
512-
}
507+
Ok(Cow::Owned(tera_fn.call(&args).map_err(err_wrap)?))
513508
}
514509

515510
fn eval_macro_call(&mut self, macro_call: &'a MacroCall, write: &mut impl Write) -> Result<()> {

0 commit comments

Comments
 (0)