Skip to content

Commit 11e24c3

Browse files
committed
Refactor functions on how they return metadata
1 parent 751b908 commit 11e24c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+688
-832
lines changed

dsc/locales/en-us.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ tableHeader_functionName = "Function"
115115
tableHeader_functionCategory = "Category"
116116
tableHeader_minArgs = "MinArgs"
117117
tableHeader_maxArgs = "MaxArgs"
118-
tableHeader_argTypes = "ArgTypes"
118+
tableHeader_argTypes = "ReturnTypes"
119119
invalidFunctionFilter = "Invalid function filter"
120120
maxInt = "maxInt"
121121
invalidManifest = "Error in manifest for"

dsc/src/subcommand.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::resolve::{get_contents, Include};
66
use crate::resource_command::{get_resource, self};
77
use crate::tablewriter::Table;
88
use crate::util::{get_input, get_schema, in_desired_state, set_dscconfigroot, validate_json, write_object, DSC_CONFIG_ROOT, EXIT_DSC_ASSERTION_FAILED, EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_INVALID_INPUT, EXIT_JSON_ERROR};
9-
use dsc_lib::functions::AcceptedArgKind;
9+
use dsc_lib::functions::FunctionArgKind;
1010
use dsc_lib::{
1111
configure::{
1212
config_doc::{
@@ -698,11 +698,11 @@ fn list_functions(functions: &FunctionDispatcher, function_name: Option<&String>
698698
}
699699
let mut include_separator = false;
700700
let accepted_arg_types= [
701-
(AcceptedArgKind::Array, "a"),
702-
(AcceptedArgKind::Boolean, "b"),
703-
(AcceptedArgKind::Number, "n"),
704-
(AcceptedArgKind::String, "s"),
705-
(AcceptedArgKind::Object, "o"),
701+
(FunctionArgKind::Array, "a"),
702+
(FunctionArgKind::Boolean, "b"),
703+
(FunctionArgKind::Number, "n"),
704+
(FunctionArgKind::String, "s"),
705+
(FunctionArgKind::Object, "o"),
706706
];
707707

708708
let asterisks = String::from("*");
@@ -726,7 +726,7 @@ fn list_functions(functions: &FunctionDispatcher, function_name: Option<&String>
726726
// construct arg_types from '-' times number of accepted_arg_types
727727
let mut arg_types = "-".repeat(accepted_arg_types.len());
728728
for (i, (arg_type, letter)) in accepted_arg_types.iter().enumerate() {
729-
if function.accepted_arg_types.contains(arg_type) {
729+
if function.return_types.contains(arg_type) {
730730
arg_types.replace_range(i..=i, letter);
731731
}
732732
}

dsc_lib/locales/en-us.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ noBooleanArgs = "Function '%{name}' does not accept boolean arguments, accepted
207207
noNumberArgs = "Function '%{name}' does not accept number arguments, accepted types are: %{accepted_args_string}"
208208
noObjectArgs = "Function '%{name}' does not accept object arguments, accepted types are: %{accepted_args_string}"
209209
noStringArgs = "Function '%{name}' does not accept string arguments, accepted types are: %{accepted_args_string}"
210+
tooFewArgs = "Function '%{name}' requires at least %{count} arguments"
211+
tooManyArgs = "Function '%{name}' does not accept more than %{count} arguments"
210212

211213
[functions.add]
212214
description = "Adds two or more numbers together"

dsc_lib/src/functions/add.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::DscError;
55
use crate::configure::context::Context;
6-
use crate::functions::{AcceptedArgKind, Function, FunctionCategory};
6+
use crate::functions::{FunctionArgKind, Function, FunctionCategory, FunctionMetadata};
77
use rust_i18n::t;
88
use serde_json::Value;
99
use tracing::debug;
@@ -12,24 +12,17 @@ use tracing::debug;
1212
pub struct Add {}
1313

1414
impl Function for Add {
15-
fn description(&self) -> String {
16-
t!("functions.add.description").to_string()
17-
}
18-
19-
fn category(&self) -> FunctionCategory {
20-
FunctionCategory::Numeric
21-
}
22-
23-
fn min_args(&self) -> usize {
24-
2
25-
}
26-
27-
fn max_args(&self) -> usize {
28-
2
29-
}
30-
31-
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
32-
vec![AcceptedArgKind::Number]
15+
fn get_metadata(&self) -> FunctionMetadata {
16+
FunctionMetadata {
17+
name: "add".to_string(),
18+
description: t!("functions.add.description").to_string(),
19+
category: FunctionCategory::Numeric,
20+
min_args: 2,
21+
max_args: 2,
22+
accepted_arg_ordered_types: vec![vec![FunctionArgKind::Number], vec![FunctionArgKind::Number]],
23+
remaining_arg_accepted_types: None,
24+
return_types: vec![FunctionArgKind::Number],
25+
}
3326
}
3427

3528
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {

dsc_lib/src/functions/and.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::DscError;
55
use crate::configure::context::Context;
6-
use crate::functions::{AcceptedArgKind, Function, FunctionCategory};
6+
use crate::functions::{FunctionArgKind, Function, FunctionCategory, FunctionMetadata};
77
use rust_i18n::t;
88
use serde_json::Value;
99
use tracing::debug;
@@ -12,24 +12,17 @@ use tracing::debug;
1212
pub struct And {}
1313

1414
impl Function for And {
15-
fn description(&self) -> String {
16-
t!("functions.and.description").to_string()
17-
}
18-
19-
fn category(&self) -> FunctionCategory {
20-
FunctionCategory::Logical
21-
}
22-
23-
fn min_args(&self) -> usize {
24-
2
25-
}
26-
27-
fn max_args(&self) -> usize {
28-
usize::MAX
29-
}
30-
31-
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
32-
vec![AcceptedArgKind::Boolean]
15+
fn get_metadata(&self) -> FunctionMetadata {
16+
FunctionMetadata {
17+
name: "and".to_string(),
18+
description: t!("functions.and.description").to_string(),
19+
category: FunctionCategory::Logical,
20+
min_args: 2,
21+
max_args: usize::MAX,
22+
accepted_arg_ordered_types: vec![vec![FunctionArgKind::Boolean], vec![FunctionArgKind::Boolean]],
23+
remaining_arg_accepted_types: Some(vec![FunctionArgKind::Boolean]),
24+
return_types: vec![FunctionArgKind::Boolean],
25+
}
3326
}
3427

3528
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {

dsc_lib/src/functions/base64.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use base64::{Engine as _, engine::general_purpose};
55

66
use crate::DscError;
77
use crate::configure::context::Context;
8-
use crate::functions::{AcceptedArgKind, FunctionCategory};
8+
use crate::functions::{FunctionArgKind, FunctionCategory, FunctionMetadata};
99
use rust_i18n::t;
1010
use serde_json::Value;
1111
use super::Function;
@@ -14,24 +14,17 @@ use super::Function;
1414
pub struct Base64 {}
1515

1616
impl Function for Base64 {
17-
fn description(&self) -> String {
18-
t!("functions.base64.description").to_string()
19-
}
20-
21-
fn category(&self) -> FunctionCategory {
22-
FunctionCategory::String
23-
}
24-
25-
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
26-
vec![AcceptedArgKind::String]
27-
}
28-
29-
fn min_args(&self) -> usize {
30-
1
31-
}
32-
33-
fn max_args(&self) -> usize {
34-
1
17+
fn get_metadata(&self) -> FunctionMetadata {
18+
FunctionMetadata {
19+
name: "base64".to_string(),
20+
description: t!("functions.base64.description").to_string(),
21+
category: FunctionCategory::String,
22+
min_args: 1,
23+
max_args: 1,
24+
accepted_arg_ordered_types: vec![vec![FunctionArgKind::String]],
25+
remaining_arg_accepted_types: None,
26+
return_types: vec![FunctionArgKind::String],
27+
}
3528
}
3629

3730
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {

dsc_lib/src/functions/bool.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::DscError;
55
use crate::configure::context::Context;
6-
use crate::functions::{AcceptedArgKind, Function, FunctionCategory};
6+
use crate::functions::{FunctionArgKind, Function, FunctionCategory, FunctionMetadata};
77
use rust_i18n::t;
88
use serde_json::Value;
99
use tracing::debug;
@@ -12,24 +12,17 @@ use tracing::debug;
1212
pub struct Bool {}
1313

1414
impl Function for Bool {
15-
fn description(&self) -> String {
16-
t!("functions.bool.description").to_string()
17-
}
18-
19-
fn category(&self) -> FunctionCategory {
20-
FunctionCategory::Logical
21-
}
22-
23-
fn min_args(&self) -> usize {
24-
1
25-
}
26-
27-
fn max_args(&self) -> usize {
28-
1
29-
}
30-
31-
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
32-
vec![AcceptedArgKind::String, AcceptedArgKind::Number]
15+
fn get_metadata(&self) -> FunctionMetadata {
16+
FunctionMetadata {
17+
name: "bool".to_string(),
18+
description: t!("functions.bool.description").to_string(),
19+
category: FunctionCategory::Logical,
20+
min_args: 1,
21+
max_args: 1,
22+
accepted_arg_ordered_types: vec![vec![FunctionArgKind::String, FunctionArgKind::Number]],
23+
remaining_arg_accepted_types: None,
24+
return_types: vec![FunctionArgKind::Boolean],
25+
}
3326
}
3427

3528
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {

dsc_lib/src/functions/coalesce.rs

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::DscError;
55
use crate::configure::context::Context;
6-
use crate::functions::{AcceptedArgKind, Function, FunctionCategory};
6+
use crate::functions::{FunctionArgKind, Function, FunctionCategory, FunctionMetadata};
77
use rust_i18n::t;
88
use serde_json::Value;
99
use tracing::debug;
@@ -12,30 +12,35 @@ use tracing::debug;
1212
pub struct Coalesce {}
1313

1414
impl Function for Coalesce {
15-
fn description(&self) -> String {
16-
t!("functions.coalesce.description").to_string()
17-
}
18-
19-
fn category(&self) -> FunctionCategory {
20-
FunctionCategory::Comparison
21-
}
22-
23-
fn min_args(&self) -> usize {
24-
1
25-
}
26-
27-
fn max_args(&self) -> usize {
28-
usize::MAX
29-
}
30-
31-
fn accepted_arg_types(&self) -> Vec<AcceptedArgKind> {
32-
vec![
33-
AcceptedArgKind::Array,
34-
AcceptedArgKind::Boolean,
35-
AcceptedArgKind::Number,
36-
AcceptedArgKind::Object,
37-
AcceptedArgKind::String,
38-
]
15+
fn get_metadata(&self) -> FunctionMetadata {
16+
FunctionMetadata {
17+
name: "coalesce".to_string(),
18+
description: t!("functions.coalesce.description").to_string(),
19+
category: FunctionCategory::Comparison,
20+
min_args: 1,
21+
max_args: usize::MAX,
22+
accepted_arg_ordered_types: vec![vec![
23+
FunctionArgKind::Array,
24+
FunctionArgKind::Boolean,
25+
FunctionArgKind::Number,
26+
FunctionArgKind::Object,
27+
FunctionArgKind::String,
28+
]],
29+
remaining_arg_accepted_types: Some(vec![
30+
FunctionArgKind::Array,
31+
FunctionArgKind::Boolean,
32+
FunctionArgKind::Number,
33+
FunctionArgKind::Object,
34+
FunctionArgKind::String,
35+
]),
36+
return_types: vec![
37+
FunctionArgKind::Array,
38+
FunctionArgKind::Boolean,
39+
FunctionArgKind::Number,
40+
FunctionArgKind::Object,
41+
FunctionArgKind::String,
42+
],
43+
}
3944
}
4045

4146
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
@@ -61,15 +66,15 @@ mod tests {
6166
fn direct_function_call_with_nulls() {
6267
let coalesce = Coalesce {};
6368
let context = Context::new();
64-
69+
6570
let args = vec![Value::Null, Value::Null, Value::String("hello".to_string())];
6671
let result = coalesce.invoke(&args, &context).unwrap();
6772
assert_eq!(result, Value::String("hello".to_string()));
68-
73+
6974
let args = vec![Value::Null, Value::Null, Value::Null];
7075
let result = coalesce.invoke(&args, &context).unwrap();
7176
assert_eq!(result, Value::Null);
72-
77+
7378
let args = vec![Value::String("first".to_string()), Value::String("second".to_string())];
7479
let result = coalesce.invoke(&args, &context).unwrap();
7580
assert_eq!(result, Value::String("first".to_string()));
@@ -79,11 +84,11 @@ mod tests {
7984
fn direct_function_call_mixed_types() {
8085
let coalesce = Coalesce {};
8186
let context = Context::new();
82-
87+
8388
let args = vec![Value::Null, serde_json::json!(42), Value::String("fallback".to_string())];
8489
let result = coalesce.invoke(&args, &context).unwrap();
8590
assert_eq!(result, serde_json::json!(42));
86-
91+
8792
let args = vec![Value::Null, Value::Bool(true)];
8893
let result = coalesce.invoke(&args, &context).unwrap();
8994
assert_eq!(result, Value::Bool(true));
@@ -93,14 +98,14 @@ mod tests {
9398
fn direct_function_call_with_arrays() {
9499
let coalesce = Coalesce {};
95100
let context = Context::new();
96-
101+
97102
let first_array = serde_json::json!(["a", "b", "c"]);
98103
let second_array = serde_json::json!(["x", "y", "z"]);
99-
104+
100105
let args = vec![Value::Null, first_array.clone(), second_array];
101106
let result = coalesce.invoke(&args, &context).unwrap();
102107
assert_eq!(result, first_array);
103-
108+
104109
let args = vec![Value::Null, Value::Null, serde_json::json!([1, 2, 3])];
105110
let result = coalesce.invoke(&args, &context).unwrap();
106111
assert_eq!(result, serde_json::json!([1, 2, 3]));
@@ -110,14 +115,14 @@ mod tests {
110115
fn direct_function_call_with_objects() {
111116
let coalesce = Coalesce {};
112117
let context = Context::new();
113-
118+
114119
let first_obj = serde_json::json!({"name": "test", "value": 42});
115120
let second_obj = serde_json::json!({"name": "fallback", "value": 0});
116-
121+
117122
let args = vec![Value::Null, first_obj.clone(), second_obj];
118123
let result = coalesce.invoke(&args, &context).unwrap();
119124
assert_eq!(result, first_obj);
120-
125+
121126
let args = vec![Value::Null, Value::Null, serde_json::json!({"key": "value"})];
122127
let result = coalesce.invoke(&args, &context).unwrap();
123128
assert_eq!(result, serde_json::json!({"key": "value"}));
@@ -127,12 +132,12 @@ mod tests {
127132
fn direct_function_call_with_empty_collections() {
128133
let coalesce = Coalesce {};
129134
let context = Context::new();
130-
135+
131136
let empty_array = serde_json::json!([]);
132137
let args = vec![Value::Null, empty_array.clone(), Value::String("fallback".to_string())];
133138
let result = coalesce.invoke(&args, &context).unwrap();
134139
assert_eq!(result, empty_array);
135-
140+
136141
let empty_obj = serde_json::json!({});
137142
let args = vec![Value::Null, empty_obj.clone(), Value::String("fallback".to_string())];
138143
let result = coalesce.invoke(&args, &context).unwrap();
@@ -144,10 +149,10 @@ mod tests {
144149
let mut parser = Statement::new().unwrap();
145150
let result = parser.parse_and_execute("[coalesce('hello', 'world')]", &Context::new()).unwrap();
146151
assert_eq!(result, "hello");
147-
152+
148153
let result = parser.parse_and_execute("[coalesce(42, 'fallback')]", &Context::new()).unwrap();
149154
assert_eq!(result, 42);
150-
155+
151156
let result = parser.parse_and_execute("[coalesce(true)]", &Context::new()).unwrap();
152157
assert_eq!(result, true);
153158
}

0 commit comments

Comments
 (0)