Skip to content

Commit 1081bd0

Browse files
committed
feat: add get_string_value for tera helper function
1 parent 4243f3d commit 1081bd0

File tree

2 files changed

+37
-27
lines changed

2 files changed

+37
-27
lines changed

.github/workflows/shared-zerv-versioning.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ on:
6060
"v_semver_major": "v{{ major }}",
6161
"v_semver_major_minor": "v{{ major }}.{{ minor }}"
6262
}
63+
# TODO: update this after release
64+
# default: >-
65+
# {
66+
# "docker_tag": "{{ semver_obj.docker }}",
67+
# "v_major": "v{{ major | default(value="0") }}",
68+
# "v_major_minor": "v{{ major | default(value="0") }}{{ prefix_if(value=minor, prefix=".") }}"
69+
# }
6370
custom_outputs:
6471
type: string
6572
required: false

src/cli/utils/template/functions.rs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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
2240
pub 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> {
3452
fn 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) }}
95110
fn 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
118130
fn 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) }}
154163
fn 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
173179
fn 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

Comments
 (0)