11mod context;
22
3- use cel_interpreter :: objects:: { Key , TryIntoValue } ;
4- use cel_interpreter :: { ExecutionError , Program , Value } ;
3+ use :: cel :: objects:: { Key , TryIntoValue } ;
4+ use :: cel :: { Context as CelContext , ExecutionError , Program , Value } ;
55use log:: { debug, warn} ;
66use pyo3:: exceptions:: { PyRuntimeError , PyTypeError , PyValueError } ;
77use pyo3:: prelude:: * ;
@@ -532,7 +532,7 @@ fn evaluate(src: String, evaluation_context: Option<&Bound<'_, PyAny>>) -> PyRes
532532 src. clone ( )
533533 } ;
534534
535- let mut environment = cel_interpreter :: Context :: default ( ) ;
535+ let mut environment = CelContext :: default ( ) ;
536536 let mut ctx = context:: Context :: new ( None , None ) ?;
537537 let mut variables_for_env = HashMap :: new ( ) ;
538538
@@ -591,60 +591,62 @@ fn evaluate(src: String, evaluation_context: Option<&Bound<'_, PyAny>>) -> PyRes
591591 } ) ?;
592592 }
593593
594- // Add functions
595- let collected_functions: Vec < ( String , Py < PyAny > ) > = Python :: with_gil ( |py| {
596- ctx. functions
597- . iter ( )
598- . map ( |( name, py_function) | ( name. clone ( ) , py_function. clone_ref ( py) ) )
599- . collect ( )
600- } ) ;
594+ // Register Python functions
595+ for ( function_name, py_function) in ctx. functions . iter ( ) {
596+ // Create a wrapper function
597+ let py_func_clone = Python :: with_gil ( |py| py_function. clone_ref ( py) ) ;
598+ let func_name_clone = function_name. clone ( ) ;
601599
602- for ( name , py_function ) in collected_functions . into_iter ( ) {
600+ // Register a function that takes Arguments (variadic) and returns a Value
603601 environment. add_function (
604- & name. clone ( ) ,
605- move |ftx : & cel_interpreter:: FunctionContext | -> cel_interpreter:: ResolveResult {
602+ function_name,
603+ move |args : :: cel:: extractors:: Arguments | -> Result < Value , ExecutionError > {
604+ let py_func = py_func_clone. clone ( ) ;
605+ let func_name = func_name_clone. clone ( ) ;
606+
606607 Python :: with_gil ( |py| {
607- // Convert arguments from Expression in ftx.args to PyObjects
608+ // Convert CEL arguments to Python objects
608609 let mut py_args = Vec :: new ( ) ;
609- for arg_expr in & ftx. args {
610- let arg_value = ftx. ptx . resolve ( arg_expr) ?;
611- let py_arg = RustyCelType ( arg_value)
610+ for cel_value in args. 0 . iter ( ) {
611+ let py_arg = RustyCelType ( cel_value. clone ( ) )
612612 . into_pyobject ( py)
613- . map_err ( |e| {
614- ExecutionError :: function_error (
615- "argument_conversion" ,
616- format ! ( "Failed to convert argument: {e}" ) ,
617- )
613+ . map_err ( |e| ExecutionError :: FunctionError {
614+ function : func_name. clone ( ) ,
615+ message : format ! ( "Failed to convert argument to Python: {e}" ) ,
618616 } ) ?
619617 . into_any ( )
620618 . unbind ( ) ;
621619 py_args. push ( py_arg) ;
622620 }
623- let py_args = PyTuple :: new ( py, py_args) . map_err ( |e| {
624- ExecutionError :: function_error (
625- "tuple_creation" ,
626- format ! ( "Failed to create tuple: {e}" ) ,
627- )
628- } ) ?;
629621
630- // Call the Python function
631- let py_result = py_function. call1 ( py, py_args) . map_err ( |e| {
622+ let py_args_tuple = PyTuple :: new ( py, py_args) . map_err ( |e| {
632623 ExecutionError :: FunctionError {
633- function : name . clone ( ) ,
634- message : e . to_string ( ) ,
624+ function : func_name . clone ( ) ,
625+ message : format ! ( "Failed to create arguments tuple: {e}" ) ,
635626 }
636627 } ) ?;
637- // Convert the PyObject to &Bound<PyAny>
638- let py_result_ref = py_result. bind ( py) ;
639628
640- // Convert the result back to Value
641- let value = RustyPyType ( py_result_ref ) . try_into_value ( ) . map_err ( |e| {
629+ // Call the Python function
630+ let py_result = py_func . call1 ( py , py_args_tuple ) . map_err ( |e| {
642631 ExecutionError :: FunctionError {
643- function : name . clone ( ) ,
644- message : format ! ( "Error calling function '{name}' : {e}" ) ,
632+ function : func_name . clone ( ) ,
633+ message : format ! ( "Python function call failed : {e}" ) ,
645634 }
646635 } ) ?;
647- Ok ( value)
636+
637+ // Convert the result back to CEL Value
638+ let py_result_ref = py_result. bind ( py) ;
639+ let cel_value =
640+ RustyPyType ( py_result_ref) . try_into_value ( ) . map_err ( |e| {
641+ ExecutionError :: FunctionError {
642+ function : func_name. clone ( ) ,
643+ message : format ! (
644+ "Failed to convert Python result to CEL value: {e}"
645+ ) ,
646+ }
647+ } ) ?;
648+
649+ Ok ( cel_value)
648650 } )
649651 } ,
650652 ) ;
@@ -671,7 +673,6 @@ fn evaluate(src: String, evaluation_context: Option<&Bound<'_, PyAny>>) -> PyRes
671673 }
672674}
673675
674- /// A Python module implemented in Rust.
675676#[ pymodule]
676677fn cel ( _py : Python < ' _ > , m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
677678 pyo3_log:: init ( ) ;
0 commit comments