@@ -5,6 +5,7 @@ use std::collections::HashMap;
5
5
6
6
use crate :: DscError ;
7
7
use crate :: configure:: context:: Context ;
8
+ use crate :: functions:: user_function:: invoke_user_function;
8
9
use rust_i18n:: t;
9
10
use schemars:: JsonSchema ;
10
11
use serde:: Serialize ;
@@ -60,6 +61,7 @@ pub mod system_root;
60
61
pub mod r#true;
61
62
pub mod union;
62
63
pub mod unique_string;
64
+ pub mod user_function;
63
65
pub mod utc_now;
64
66
pub mod variables;
65
67
@@ -197,6 +199,10 @@ impl FunctionDispatcher {
197
199
/// This function will return an error if the function fails to execute.
198
200
pub fn invoke ( & self , name : & str , args : & [ Value ] , context : & Context ) -> Result < Value , DscError > {
199
201
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
+ }
200
206
return Err ( DscError :: Parser ( t ! ( "functions.unknownFunction" , name = name) . to_string ( ) ) ) ;
201
207
} ;
202
208
@@ -224,32 +230,32 @@ impl FunctionDispatcher {
224
230
break ;
225
231
}
226
232
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] ) ?;
228
234
}
229
235
230
236
// if we have remaining args, they must match one of the remaining_arg_types
231
237
if let Some ( remaining_arg_types) = metadata. remaining_arg_accepted_types {
232
238
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) ?;
234
240
}
235
241
}
236
242
237
243
function. invoke ( args, context)
238
244
}
239
245
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 > {
241
247
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 ( ) ) ) ;
243
249
} 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 ( ) ) ) ;
245
251
} 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 ( ) ) ) ;
247
253
} 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 ( ) ) ) ;
249
255
} 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 ( ) ) ) ;
251
257
} 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 ( ) ) ) ;
253
259
}
254
260
Ok ( ( ) )
255
261
}
0 commit comments