Skip to content

Commit

Permalink
Merge pull request #353 from tgauth/add-sub-function
Browse files Browse the repository at this point in the history
implement sub function
  • Loading branch information
SteveL-MSFT authored Mar 7, 2024
2 parents f4ed69b + 86968f4 commit 28cfb87
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions dsc_lib/src/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod envvar;
pub mod mul;
pub mod parameters;
pub mod resource_id;
pub mod sub;

/// The kind of argument that a function accepts.
#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -64,6 +65,7 @@ impl FunctionDispatcher {
functions.insert("mul".to_string(), Box::new(mul::Mul{}));
functions.insert("parameters".to_string(), Box::new(parameters::Parameters{}));
functions.insert("resourceId".to_string(), Box::new(resource_id::ResourceId{}));
functions.insert("sub".to_string(), Box::new(sub::Sub{}));
Self {
functions,
}
Expand Down
76 changes: 76 additions & 0 deletions dsc_lib/src/functions/sub.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::DscError;
use crate::configure::context::Context;
use crate::functions::{AcceptedArgKind, Function};
use serde_json::Value;
use tracing::debug;

#[derive(Debug, Default)]
pub struct Sub {}

impl Function for Sub {
fn min_args(&self) -> usize {
2
}

fn max_args(&self) -> usize {
2
}

fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
vec![AcceptedArgKind::Number]
}

fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
debug!("sub function");
if let (Some(arg1), Some(arg2)) = (args[0].as_i64(), args[1].as_i64()) {
Ok(Value::Number((arg1 - arg2).into()))
} else {
Err(DscError::Parser("Invalid argument(s)".to_string()))
}
}
}

#[cfg(test)]
mod tests {
use crate::configure::context::Context;
use crate::parser::Statement;

#[test]
fn numbers() {
let mut parser = Statement::new().unwrap();
let result = parser.parse_and_execute("[sub(7, 3)]", &Context::new()).unwrap();
assert_eq!(result, 4);
}

#[test]
fn nested() {
let mut parser = Statement::new().unwrap();
let result = parser.parse_and_execute("[sub(9, sub(5, 3))]", &Context::new()).unwrap();
assert_eq!(result, 7);
}

#[test]
fn invalid_one_parameter() {
let mut parser = Statement::new().unwrap();
let result = parser.parse_and_execute("[sub(5)]", &Context::new());
assert!(result.is_err());
}

#[test]
fn overflow_result() {
let mut parser = Statement::new().unwrap();
// max value for i64 is 2^63 -1 (or 9,223,372,036,854,775,807)
let result = parser.parse_and_execute("[sub(9223372036854775807, -2)]", &Context::new());
assert!(result.is_err());
}

#[test]
fn overflow_input() {
let mut parser = Statement::new().unwrap();
let result = parser.parse_and_execute("[sub(9223372036854775808, 2)]", &Context::new());
assert!(result.is_err());
}
}

0 comments on commit 28cfb87

Please sign in to comment.