@@ -18,6 +18,24 @@ mod timestamp_patterns {
1818 pub const COMPACT_DATETIME : & str = "compact_datetime" ;
1919}
2020
21+ /// Extract string value from any Tera Value type
22+ /// This function converts numbers, booleans, and other types to strings
23+ fn get_string_value (
24+ args : & std:: collections:: HashMap < String , Value > ,
25+ key : & str ,
26+ ) -> Result < String , tera:: Error > {
27+ args. get ( key)
28+ . map ( |v| match v {
29+ Value :: String ( s) => s. clone ( ) ,
30+ Value :: Number ( n) => n. to_string ( ) ,
31+ Value :: Bool ( b) => b. to_string ( ) ,
32+ Value :: Null => String :: new ( ) ,
33+ Value :: Array ( _) => v. to_string ( ) ,
34+ Value :: Object ( _) => v. to_string ( ) ,
35+ } )
36+ . ok_or_else ( || tera:: Error :: msg ( format ! ( "Missing required parameter '{}'" , key) ) )
37+ }
38+
2139/// Register custom Tera functions
2240pub fn register_functions ( tera : & mut Tera ) -> Result < ( ) , ZervError > {
2341 tera. register_function ( "sanitize" , Box :: new ( sanitize_function) ) ;
@@ -34,10 +52,7 @@ pub fn register_functions(tera: &mut Tera) -> Result<(), ZervError> {
3452fn sanitize_function (
3553 args : & std:: collections:: HashMap < String , Value > ,
3654) -> Result < Value , tera:: Error > {
37- let value = args
38- . get ( "value" )
39- . and_then ( |v| v. as_str ( ) )
40- . ok_or_else ( || tera:: Error :: msg ( "sanitize function requires a 'value' parameter" ) ) ?;
55+ let value = get_string_value ( args, "value" ) ?;
4156
4257 // Check for preset format
4358 let preset = args. get ( "preset" ) . and_then ( |v| v. as_str ( ) ) ;
@@ -61,11 +76,11 @@ fn sanitize_function(
6176 let sanitized = if let Some ( preset) = preset {
6277 // Use preset format
6378 match preset {
64- "semver_str" | "semver" | "dotted" => Sanitizer :: semver_str ( ) . sanitize ( value) ,
79+ "semver_str" | "semver" | "dotted" => Sanitizer :: semver_str ( ) . sanitize ( & value) ,
6580 "pep440_local_str" | "pep440" | "lower_dotted" => {
66- Sanitizer :: pep440_local_str ( ) . sanitize ( value)
81+ Sanitizer :: pep440_local_str ( ) . sanitize ( & value)
6782 }
68- "uint" => Sanitizer :: uint ( ) . sanitize ( value) ,
83+ "uint" => Sanitizer :: uint ( ) . sanitize ( & value) ,
6984 _ => {
7085 return Err ( tera:: Error :: msg ( format ! (
7186 "Unknown sanitize preset: {}" ,
@@ -81,10 +96,10 @@ fn sanitize_function(
8196 keep_zeros. unwrap_or ( false ) ,
8297 max_length. map ( |l| l as usize ) ,
8398 ) ;
84- sanitizer. sanitize ( value)
99+ sanitizer. sanitize ( & value)
85100 } else {
86101 // Default to dotted preset if no parameters specified
87- Sanitizer :: semver_str ( ) . sanitize ( value)
102+ Sanitizer :: semver_str ( ) . sanitize ( & value)
88103 } ;
89104
90105 Ok ( Value :: String ( sanitized) )
@@ -93,10 +108,7 @@ fn sanitize_function(
93108/// Generate hex hash of string with configurable length
94109/// Usage: {{ hash(value, length=7) }}
95110fn hash_function ( args : & std:: collections:: HashMap < String , Value > ) -> Result < Value , tera:: Error > {
96- let input = args
97- . get ( "value" )
98- . and_then ( |v| v. as_str ( ) )
99- . ok_or_else ( || tera:: Error :: msg ( "hash function requires a 'value' parameter" ) ) ?;
111+ let input = get_string_value ( args, "value" ) ?;
100112
101113 let length = args. get ( "length" ) . and_then ( |v| v. as_u64 ( ) ) . unwrap_or ( 7 ) as usize ;
102114
@@ -118,10 +130,7 @@ fn hash_function(args: &std::collections::HashMap<String, Value>) -> Result<Valu
118130fn hash_int_function (
119131 args : & std:: collections:: HashMap < String , Value > ,
120132) -> Result < Value , tera:: Error > {
121- let input = args
122- . get ( "value" )
123- . and_then ( |v| v. as_str ( ) )
124- . ok_or_else ( || tera:: Error :: msg ( "hash_int function requires a 'value' parameter" ) ) ?;
133+ let input = get_string_value ( args, "value" ) ?;
125134
126135 let length = args. get ( "length" ) . and_then ( |v| v. as_u64 ( ) ) . unwrap_or ( 7 ) as usize ;
127136
@@ -152,17 +161,14 @@ fn hash_int_function(
152161/// Extract prefix from string with configurable length
153162/// Usage: {{ prefix(value, length=10) }}
154163fn prefix_function ( args : & std:: collections:: HashMap < String , Value > ) -> Result < Value , tera:: Error > {
155- let input = args
156- . get ( "value" )
157- . and_then ( |v| v. as_str ( ) )
158- . ok_or_else ( || tera:: Error :: msg ( "prefix function requires a 'value' parameter" ) ) ?;
164+ let input = get_string_value ( args, "value" ) ?;
159165
160166 let length = args. get ( "length" ) . and_then ( |v| v. as_u64 ( ) ) . unwrap_or ( 10 ) as usize ;
161167
162168 let prefix = if input. len ( ) > length {
163169 & input[ ..length]
164170 } else {
165- input
171+ & input
166172 } ;
167173
168174 Ok ( Value :: String ( prefix. to_string ( ) ) )
@@ -173,10 +179,7 @@ fn prefix_function(args: &std::collections::HashMap<String, Value>) -> Result<Va
173179fn prefix_if_function (
174180 args : & std:: collections:: HashMap < String , Value > ,
175181) -> Result < Value , tera:: Error > {
176- let value = args
177- . get ( "value" )
178- . and_then ( |v| v. as_str ( ) )
179- . ok_or_else ( || tera:: Error :: msg ( "prefix_if function requires a 'value' parameter" ) ) ?;
182+ let value = get_string_value ( args, "value" ) ?;
180183
181184 let prefix = args
182185 . get ( "prefix" )
@@ -401,7 +404,7 @@ mod tests {
401404 result
402405 . unwrap_err( )
403406 . to_string( )
404- . contains( "'value' parameter " )
407+ . contains( "Missing required parameter 'value'" )
405408 ) ;
406409 }
407410
0 commit comments