Skip to content

Commit ade20c6

Browse files
authored
Merge pull request #349 from tgauth/add-div-function
add div function
2 parents e2a1b3d + a43d298 commit ade20c6

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

dsc_lib/src/functions/div.rs

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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, Function};
7+
use serde_json::Value;
8+
use tracing::debug;
9+
10+
#[derive(Debug, Default)]
11+
pub struct Div {}
12+
13+
impl Function for Div {
14+
fn min_args(&self) -> usize {
15+
2
16+
}
17+
18+
fn max_args(&self) -> usize {
19+
2
20+
}
21+
22+
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
23+
vec![AcceptedArgKind::Number]
24+
}
25+
26+
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
27+
debug!("div function");
28+
if let (Some(arg1), Some(arg2)) = (args[0].as_i64(), args[1].as_i64()) {
29+
if let Some(value) = arg1.checked_div(arg2) {
30+
Ok(Value::Number(value.into()))
31+
} else {
32+
Err(DscError::Parser("Cannot divide by zero".to_string()))
33+
}
34+
} else {
35+
Err(DscError::Parser("Invalid argument(s)".to_string()))
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 numbers() {
47+
let mut parser = Statement::new().unwrap();
48+
let result = parser.parse_and_execute("[div(8, 3)]", &Context::new()).unwrap();
49+
assert_eq!(result, 2);
50+
}
51+
52+
#[test]
53+
fn nested() {
54+
let mut parser = Statement::new().unwrap();
55+
let result = parser.parse_and_execute("[div(18, div(9, 3))]", &Context::new()).unwrap();
56+
assert_eq!(result, 6);
57+
}
58+
59+
#[test]
60+
fn invalid_one_parameter() {
61+
let mut parser = Statement::new().unwrap();
62+
let result = parser.parse_and_execute("[div(5)]", &Context::new());
63+
assert!(result.is_err());
64+
}
65+
66+
#[test]
67+
fn invalid_div_by_zero() {
68+
let mut parser = Statement::new().unwrap();
69+
let result = parser.parse_and_execute("[div(5, 0)]", &Context::new());
70+
assert!(result.is_err());
71+
}
72+
73+
#[test]
74+
fn overflow_input() {
75+
let mut parser = Statement::new().unwrap();
76+
// max value for i64 is 2^63 -1 (or 9,223,372,036,854,775,807)
77+
let result = parser.parse_and_execute("[div(9223372036854775808, 2)]", &Context::new());
78+
assert!(result.is_err());
79+
}
80+
}
81+

dsc_lib/src/functions/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde_json::Value;
1010
pub mod base64;
1111
pub mod concat;
1212
pub mod create_array;
13+
pub mod div;
1314
pub mod envvar;
1415
pub mod parameters;
1516
pub mod resource_id;
@@ -57,6 +58,7 @@ impl FunctionDispatcher {
5758
functions.insert("base64".to_string(), Box::new(base64::Base64{}));
5859
functions.insert("concat".to_string(), Box::new(concat::Concat{}));
5960
functions.insert("createArray".to_string(), Box::new(create_array::CreateArray{}));
61+
functions.insert("div".to_string(), Box::new(div::Div{}));
6062
functions.insert("envvar".to_string(), Box::new(envvar::Envvar{}));
6163
functions.insert("parameters".to_string(), Box::new(parameters::Parameters{}));
6264
functions.insert("resourceId".to_string(), Box::new(resource_id::ResourceId{}));

0 commit comments

Comments
 (0)