@@ -8,9 +8,9 @@ use minijinja as mj;
88use neon:: prelude:: * ;
99use std:: cell:: RefCell ;
1010
11- use crate :: template:: workers:: { JinjaEngineWorkerJob , JinjaEngineWorkerPool } ;
1211#[ cfg( feature = "python" ) ]
13- use pyo3:: { exceptions:: PyNotImplementedError , prelude:: * , types:: PyTuple , AsPyPointer } ;
12+ use crate :: template:: engine_python;
13+ use crate :: template:: workers:: { JinjaEngineWorkerJob , JinjaEngineWorkerPool } ;
1414
1515struct JinjaEngine {
1616 inner : mj:: Environment < ' static > ,
@@ -53,78 +53,7 @@ impl JinjaEngine {
5353 engine. set_auto_escape_callback ( |_name : & str | mj:: AutoEscape :: Json ) ;
5454
5555 #[ cfg( feature = "python" ) ]
56- {
57- let filters = options
58- . get_value ( cx, "filters" ) ?
59- . downcast_or_throw :: < JsObject , _ > ( cx) ?;
60-
61- let filter_names = filters. get_own_property_names ( cx) ?;
62- for i in 0 ..filter_names. len ( cx) {
63- let filter_name: Handle < JsString > = filter_names. get ( cx, i) ?;
64- let filter_fun = CLRepr :: from_js_ref ( filters. get_value ( cx, filter_name) ?, cx) ?;
65-
66- let py_fun = match filter_fun {
67- CLRepr :: PythonRef ( py_ref) => match py_ref {
68- PythonRef :: PyFunction ( py_fun_ref)
69- | PythonRef :: PyExternalFunction ( py_fun_ref) => py_fun_ref,
70- other => {
71- return cx. throw_error ( format ! (
72- "minijinja::filter must be a function, actual: CLRepr::PythonRef({:?})" ,
73- other
74- ) )
75- }
76- } ,
77- other => {
78- return cx. throw_error ( format ! (
79- "minijinja::filter must be a function, actual: {:?}" ,
80- other. kind( )
81- ) )
82- }
83- } ;
84-
85- engine. add_filter (
86- filter_name. value ( cx) ,
87- move |_state : & mj:: State ,
88- args : & [ mj:: value:: Value ] |
89- -> Result < mj:: value:: Value , mj:: Error > {
90- let mut arguments = Vec :: with_capacity ( args. len ( ) ) ;
91-
92- for arg in args {
93- arguments. push ( from_minijinja_value ( arg) ?) ;
94- }
95-
96- let python_call_res = Python :: with_gil ( |py| {
97- let mut args_tuple = Vec :: with_capacity ( args. len ( ) ) ;
98-
99- for arg in arguments {
100- args_tuple. push ( arg. into_py ( py) ?) ;
101- }
102-
103- let tuple = PyTuple :: new ( py, args_tuple) ;
104-
105- let call_res = py_fun. call1 ( py, tuple) ?;
106-
107- let is_coroutine =
108- unsafe { pyo3:: ffi:: PyCoro_CheckExact ( call_res. as_ptr ( ) ) == 1 } ;
109- if is_coroutine {
110- Err ( PyErr :: new :: < PyNotImplementedError , _ > (
111- "Calling async is not supported" ,
112- ) )
113- } else {
114- CLRepr :: from_python_ref ( call_res. as_ref ( py) )
115- }
116- } ) ;
117- match python_call_res {
118- Ok ( r) => Ok ( to_minijinja_value ( r) ) ,
119- Err ( err) => Err ( mj:: Error :: new (
120- minijinja:: ErrorKind :: InvalidOperation ,
121- format ! ( "Error while calling filter: {}" , err) ,
122- ) ) ,
123- }
124- } ,
125- )
126- }
127- }
56+ engine_python:: mj_inject_python_extension ( cx, options, & mut engine) ?;
12857
12958 let workers_count = {
13059 let workers_count_float = options
0 commit comments