Skip to content

Commit 5a2a744

Browse files
authored
Merge pull request #776 from SteveL-MSFT/if-function
Add `if()` function
2 parents 66047e0 + cec2387 commit 5a2a744

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

dsc_lib/locales/en-us.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ divideByZero = "Cannot divide by zero"
197197
[functions.envvar]
198198
notFound = "Environment variable not found"
199199

200+
[functions.if]
201+
conditionNotBoolean = "Condition is not a boolean"
202+
200203
[functions.int]
201204
invalidInput = "invalid input string"
202205
parseStringError = "unable to parse string to int"

dsc_lib/src/functions/if.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
use crate::DscError;
5+
use crate::configure::context::Context;
6+
use crate::functions::AcceptedArgKind;
7+
use super::Function;
8+
use rust_i18n::t;
9+
use serde_json::Value;
10+
11+
#[derive(Debug, Default)]
12+
pub struct If {}
13+
14+
impl Function for If {
15+
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
16+
vec![AcceptedArgKind::Boolean, AcceptedArgKind::String, AcceptedArgKind::Number, AcceptedArgKind::Array, AcceptedArgKind::Object]
17+
}
18+
19+
fn min_args(&self) -> usize {
20+
3
21+
}
22+
23+
fn max_args(&self) -> usize {
24+
3
25+
}
26+
27+
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
28+
let Some(condition) = args[0].as_bool() else {
29+
return Err(DscError::Function("if".to_string(), t!("functions.if.conditionNotBoolean").to_string()));
30+
};
31+
32+
if condition {
33+
Ok(args[1].clone())
34+
} else {
35+
Ok(args[2].clone())
36+
}
37+
}
38+
}
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use crate::configure::context::Context;
43+
use crate::parser::Statement;
44+
45+
#[test]
46+
fn invalid_condition() {
47+
let mut parser = Statement::new().unwrap();
48+
let result = parser.parse_and_execute("[if('PATH', 1 , 2)]", &Context::new());
49+
assert!(result.is_err());
50+
}
51+
52+
#[test]
53+
fn condition_true() {
54+
let mut parser = Statement::new().unwrap();
55+
let result = parser.parse_and_execute("[if(true, 'left', 'right')]", &Context::new()).unwrap();
56+
assert_eq!(result, "left");
57+
}
58+
59+
#[test]
60+
fn condition_false() {
61+
let mut parser = Statement::new().unwrap();
62+
let result = parser.parse_and_execute("[if(false, 'left', 'right')]", &Context::new()).unwrap();
63+
assert_eq!(result, "right");
64+
}
65+
}

dsc_lib/src/functions/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod create_array;
1515
pub mod div;
1616
pub mod envvar;
1717
pub mod equals;
18+
pub mod r#if;
1819
pub mod int;
1920
pub mod max;
2021
pub mod min;
@@ -75,6 +76,7 @@ impl FunctionDispatcher {
7576
functions.insert("div".to_string(), Box::new(div::Div{}));
7677
functions.insert("envvar".to_string(), Box::new(envvar::Envvar{}));
7778
functions.insert("equals".to_string(), Box::new(equals::Equals{}));
79+
functions.insert("if".to_string(), Box::new(r#if::If{}));
7880
functions.insert("int".to_string(), Box::new(int::Int{}));
7981
functions.insert("max".to_string(), Box::new(max::Max{}));
8082
functions.insert("min".to_string(), Box::new(min::Min{}));

0 commit comments

Comments
 (0)