1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! Core trait for filter-functions that support both function and filter syntax.
//!
//! This module provides the `FilterFunction` trait which allows a single implementation
//! to be registered as both a MiniJinja function and filter.
//!
//! # Example
//!
//! ```rust,ignore
//! use crate::filter_functions::traits::FilterFunction;
//! use crate::functions::metadata::{FunctionMetadata, ArgumentMetadata, SyntaxVariants};
//!
//! pub struct Sha256;
//!
//! impl FilterFunction for Sha256 {
//! const NAME: &'static str = "sha256";
//! const METADATA: FunctionMetadata = FunctionMetadata {
//! name: "sha256",
//! category: "hash",
//! description: "Compute SHA-256 hash of a string",
//! arguments: &[ArgumentMetadata {
//! name: "string",
//! arg_type: "string",
//! required: true,
//! default: None,
//! description: "The string to hash",
//! }],
//! return_type: "string",
//! examples: &["{{ sha256(string=\"hello\") }}", "{{ \"hello\" | sha256 }}"],
//! syntax: SyntaxVariants::FUNCTION_AND_FILTER,
//! };
//!
//! fn call_as_function(kwargs: Kwargs) -> Result<Value, Error> {
//! let input: String = kwargs.get("string")?;
//! Ok(Value::from(Self::hash(&input)))
//! }
//!
//! fn call_as_filter(value: &Value, _kwargs: Kwargs) -> Result<Value, Error> {
//! let input = value.as_str().ok_or_else(|| {
//! Error::new(ErrorKind::InvalidOperation, "sha256 requires a string")
//! })?;
//! Ok(Value::from(Self::hash(input)))
//! }
//! }
//!
//! // Registration:
//! Sha256::register(&mut env);
//! ```
use crateFunctionMetadata;
use Kwargs;
use ;
/// Trait for types that can be registered as both a MiniJinja function and filter.
///
/// Implementors define how to handle both calling conventions:
/// - Function: `{{ name(arg="value") }}` - all arguments come from kwargs
/// - Filter: `{{ value | name(arg="value") }}` - first arg is piped, rest from kwargs
///
/// # Usage
///
/// Both syntaxes are equivalent and produce the same result:
/// ```jinja
/// {{ sha256(string="hello") }}
/// {{ "hello" | sha256 }}
/// ```
///
/// Filters can be chained:
/// ```jinja
/// {{ "hello" | sha256 | base64_encode }}
/// ```