@@ -5,6 +5,7 @@ use std::collections::HashMap;
55
66use crate :: DscError ;
77use crate :: configure:: context:: Context ;
8+ use crate :: functions:: user_function:: invoke_user_function;
89use rust_i18n:: t;
910use schemars:: JsonSchema ;
1011use serde:: Serialize ;
@@ -60,6 +61,7 @@ pub mod system_root;
6061pub mod r#true;
6162pub mod union;
6263pub mod unique_string;
64+ pub mod user_function;
6365pub mod utc_now;
6466pub mod variables;
6567
@@ -197,6 +199,10 @@ impl FunctionDispatcher {
197199 /// This function will return an error if the function fails to execute.
198200 pub fn invoke ( & self , name : & str , args : & [ Value ] , context : & Context ) -> Result < Value , DscError > {
199201 let Some ( function) = self . functions . get ( name) else {
202+ // if function name contains a period, it might be a user function
203+ if name. contains ( '.' ) {
204+ return invoke_user_function ( name, args, context) ;
205+ }
200206 return Err ( DscError :: Parser ( t ! ( "functions.unknownFunction" , name = name) . to_string ( ) ) ) ;
201207 } ;
202208
@@ -224,32 +230,32 @@ impl FunctionDispatcher {
224230 break ;
225231 }
226232
227- Self :: check_arg_against_expected_types ( value, & metadata. accepted_arg_ordered_types [ index] ) ?;
233+ Self :: check_arg_against_expected_types ( name , value, & metadata. accepted_arg_ordered_types [ index] ) ?;
228234 }
229235
230236 // if we have remaining args, they must match one of the remaining_arg_types
231237 if let Some ( remaining_arg_types) = metadata. remaining_arg_accepted_types {
232238 for value in args. iter ( ) . skip ( metadata. accepted_arg_ordered_types . len ( ) ) {
233- Self :: check_arg_against_expected_types ( value, & remaining_arg_types) ?;
239+ Self :: check_arg_against_expected_types ( name , value, & remaining_arg_types) ?;
234240 }
235241 }
236242
237243 function. invoke ( args, context)
238244 }
239245
240- fn check_arg_against_expected_types ( arg : & Value , expected_types : & [ FunctionArgKind ] ) -> Result < ( ) , DscError > {
246+ fn check_arg_against_expected_types ( name : & str , arg : & Value , expected_types : & [ FunctionArgKind ] ) -> Result < ( ) , DscError > {
241247 if arg. is_array ( ) && !expected_types. contains ( & FunctionArgKind :: Array ) {
242- return Err ( DscError :: Parser ( t ! ( "functions.noArrayArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
248+ return Err ( DscError :: Parser ( t ! ( "functions.noArrayArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
243249 } else if arg. is_boolean ( ) && !expected_types. contains ( & FunctionArgKind :: Boolean ) {
244- return Err ( DscError :: Parser ( t ! ( "functions.noBooleanArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
250+ return Err ( DscError :: Parser ( t ! ( "functions.noBooleanArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
245251 } else if arg. is_null ( ) && !expected_types. contains ( & FunctionArgKind :: Null ) {
246- return Err ( DscError :: Parser ( t ! ( "functions.noNullArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
252+ return Err ( DscError :: Parser ( t ! ( "functions.noNullArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
247253 } else if arg. is_number ( ) && !expected_types. contains ( & FunctionArgKind :: Number ) {
248- return Err ( DscError :: Parser ( t ! ( "functions.noNumberArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
254+ return Err ( DscError :: Parser ( t ! ( "functions.noNumberArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
249255 } else if arg. is_object ( ) && !expected_types. contains ( & FunctionArgKind :: Object ) {
250- return Err ( DscError :: Parser ( t ! ( "functions.noObjectArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
256+ return Err ( DscError :: Parser ( t ! ( "functions.noObjectArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
251257 } else if arg. is_string ( ) && !expected_types. contains ( & FunctionArgKind :: String ) {
252- return Err ( DscError :: Parser ( t ! ( "functions.noStringArgs" , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
258+ return Err ( DscError :: Parser ( t ! ( "functions.noStringArgs" , name = name , accepted_args_string = expected_types. iter( ) . map( std:: string:: ToString :: to_string) . collect:: <Vec <_>>( ) . join( ", " ) ) . to_string ( ) ) ) ;
253259 }
254260 Ok ( ( ) )
255261 }
0 commit comments