From a0ce056bae90934b5e0da321575bc667fc155b4f Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Sat, 4 Apr 2020 12:14:54 +0000 Subject: [PATCH] New array_set command --- CHANGELOG.md | 1 + docs/sdk.md | 60 +++++++++++++ .../src/sdk/std/collections/array_set/help.md | 22 +++++ .../src/sdk/std/collections/array_set/mod.rs | 90 +++++++++++++++++++ .../sdk/std/collections/array_set/mod_test.rs | 57 ++++++++++++ duckscript_sdk/src/sdk/std/collections/mod.rs | 2 + test/std/collections/array_set_test.ds | 37 ++++++++ 7 files changed, 269 insertions(+) create mode 100644 duckscript_sdk/src/sdk/std/collections/array_set/help.md create mode 100755 duckscript_sdk/src/sdk/std/collections/array_set/mod.rs create mode 100644 duckscript_sdk/src/sdk/std/collections/array_set/mod_test.rs create mode 100644 test/std/collections/array_set_test.ds diff --git a/CHANGELOG.md b/CHANGELOG.md index 628c27b..0e39103 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### v0.3.2 +* New array_set command. * New array_get command #94 ### v0.3.1 (2020-03-28) diff --git a/docs/sdk.md b/docs/sdk.md index ef31bcf..cdad318 100644 --- a/docs/sdk.md +++ b/docs/sdk.md @@ -9,11 +9,13 @@ * [std::ShowCommandDocumentation (man)](#std__ShowCommandDocumentation) * [std::collections::Array (array)](#std__collections__Array) * [std::collections::ArrayConcat (array_concat)](#std__collections__ArrayConcat) +* [std::collections::ArrayGet (array_get)](#std__collections__ArrayGet) * [std::collections::ArrayIsEmpty (array_is_empty)](#std__collections__ArrayIsEmpty) * [std::collections::ArrayJoin (array_join)](#std__collections__ArrayJoin) * [std::collections::ArrayLength (array_length, arrlen)](#std__collections__ArrayLength) * [std::collections::ArrayPop (array_pop)](#std__collections__ArrayPop) * [std::collections::ArrayPush (array_push)](#std__collections__ArrayPush) +* [std::collections::ArraySet (array_set)](#std__collections__ArraySet) * [std::collections::IsArray (is_array)](#std__collections__IsArray) * [std::collections::IsMap (is_map)](#std__collections__IsMap) * [std::collections::Map (map)](#std__collections__Map) @@ -512,6 +514,35 @@ set ${scope::array_concat::array} #### Aliases: array_concat + +## std::collections::ArrayGet +```sh +var = array_get handle index +``` + +Returns the element from the array at a given index or none if the index is bigger than the array length. + +#### Parameters + +* The array handle. +* The element index. + +#### Return Value + +The element at the given index from the array or none. + +#### Examples + +```sh +handle = array 1 2 3 +element = array_get ${handle} 2 +assert_eq ${element} 3 +``` + + +#### Aliases: +array_get + ## std::collections::ArrayIsEmpty @@ -720,6 +751,35 @@ assert_eq ${last_element} 4 #### Aliases: array_push + +## std::collections::ArraySet +```sh +var = array_get handle index +``` + +Returns the element from the array at a given index or none if the index is bigger than the array length. + +#### Parameters + +* The array handle. +* The element index. + +#### Return Value + +The element at the given index from the array or none. + +#### Examples + +```sh +handle = array 1 2 3 +element = array_get ${handle} 2 +assert_eq ${element} 3 +``` + + +#### Aliases: +array_set + ## std::collections::IsArray ```sh diff --git a/duckscript_sdk/src/sdk/std/collections/array_set/help.md b/duckscript_sdk/src/sdk/std/collections/array_set/help.md new file mode 100644 index 0000000..2292d1b --- /dev/null +++ b/duckscript_sdk/src/sdk/std/collections/array_set/help.md @@ -0,0 +1,22 @@ +```sh +var = array_get handle index +``` + +Returns the element from the array at a given index or none if the index is bigger than the array length. + +#### Parameters + +* The array handle. +* The element index. + +#### Return Value + +The element at the given index from the array or none. + +#### Examples + +```sh +handle = array 1 2 3 +element = array_get ${handle} 2 +assert_eq ${element} 3 +``` diff --git a/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs new file mode 100755 index 0000000..ae11024 --- /dev/null +++ b/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs @@ -0,0 +1,90 @@ +use crate::utils::pckg; +use crate::utils::state::{get_handles_sub_state, mutate_list}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; + +#[cfg(test)] +#[path = "./mod_test.rs"] +mod mod_test; + +#[derive(Clone)] +pub(crate) struct CommandImpl { + package: String, +} + +impl Command for CommandImpl { + fn name(&self) -> String { + pckg::concat(&self.package, "ArraySet") + } + + fn aliases(&self) -> Vec { + vec!["array_set".to_string()] + } + + fn help(&self) -> String { + include_str!("help.md").to_string() + } + + fn clone_and_box(&self) -> Box { + Box::new((*self).clone()) + } + + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + arguments: Vec, + state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + ) -> CommandResult { + if arguments.len() < 3 { + CommandResult::Error("Invalid input provided.".to_string()) + } else { + let state = get_handles_sub_state(state); + + let key = arguments[0].clone(); + let index: usize = match arguments[1].parse() { + Ok(value) => value, + Err(_) => { + return CommandResult::Error( + format!("Non numeric value: {} provided.", &arguments[1]).to_string(), + ); + } + }; + + let result = mutate_list(key, state, |list| { + let list_length = list.len(); + + if list_length > index { + list[index] = StateValue::String(arguments[2].clone()); + + Ok(Some("true".to_string())) + } else { + Err(format!( + "Index: {} is greater than list size: {}", + index, list_length + )) + } + }); + + match result { + Ok(value) => CommandResult::Continue(value), + Err(error) => CommandResult::Error(error), + } + } + } +} + +pub(crate) fn create(package: &str) -> Box { + Box::new(CommandImpl { + package: package.to_string(), + }) +} diff --git a/duckscript_sdk/src/sdk/std/collections/array_set/mod_test.rs b/duckscript_sdk/src/sdk/std/collections/array_set/mod_test.rs new file mode 100644 index 0000000..7df631a --- /dev/null +++ b/duckscript_sdk/src/sdk/std/collections/array_set/mod_test.rs @@ -0,0 +1,57 @@ +use super::*; +use crate::sdk::std::collections::array; +use crate::test; +use crate::test::CommandValidation; + +#[test] +fn common_functions() { + test::test_common_command_functions(create("")); +} + +#[test] +fn run_no_args() { + test::run_script_and_error(vec![create("")], "out = array_set", "out"); +} + +#[test] +fn run_only_handle() { + test::run_script_and_error(vec![create("")], "out = array_set handle", "out"); +} + +#[test] +fn run_only_handle_and_index() { + test::run_script_and_error(vec![create("")], "out = array_set handle 3", "out"); +} + +#[test] +fn run_not_found() { + test::run_script_and_error( + vec![create("")], + "out = array_set bad_handle 2 value", + "out", + ); +} + +#[test] +fn run_found() { + test::run_script_and_validate( + vec![create(""), array::create("")], + r#" + handle = array a b c "d e" + out = array_set ${handle} 3 value + "#, + CommandValidation::Match("out".to_string(), "true".to_string()), + ); +} + +#[test] +fn run_found_out_of_bounds() { + test::run_script_and_error( + vec![create(""), array::create("")], + r#" + handle = array a b c "d e" + out = array_set ${handle} 20 value + "#, + "out", + ); +} diff --git a/duckscript_sdk/src/sdk/std/collections/mod.rs b/duckscript_sdk/src/sdk/std/collections/mod.rs index af1970e..b707d7e 100755 --- a/duckscript_sdk/src/sdk/std/collections/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/mod.rs @@ -6,6 +6,7 @@ mod array_join; pub(crate) mod array_length; pub(crate) mod array_pop; mod array_push; +mod array_set; mod is_array; mod is_map; mod map; @@ -34,6 +35,7 @@ pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptEr commands.set(array_concat::create(&package)?)?; commands.set(array_get::create(&package))?; commands.set(array_push::create(&package))?; + commands.set(array_set::create(&package))?; commands.set(array_is_empty::create(&package)?)?; commands.set(array_join::create(&package)?)?; commands.set(array_length::create(&package))?; diff --git a/test/std/collections/array_set_test.ds b/test/std/collections/array_set_test.ds new file mode 100644 index 0000000..b21d7dc --- /dev/null +++ b/test/std/collections/array_set_test.ds @@ -0,0 +1,37 @@ + +fn test_array_with_data + arr = array 1 + + element = array_get ${arr} 0 + assert_eq ${element} 1 + + result = array_set ${arr} 0 10 + assert ${result} + element = array_get ${arr} 0 + assert_eq ${element} 10 + + result = array_set ${arr} 0 100 + assert ${result} + element = array_get ${arr} 0 + assert_eq ${element} 100 + + result = array_set ${arr} 1 10 + assert_false ${result} + + released = release ${arr} + assert ${released} +end + +fn test_array_no_data + arr = array + + element = array_get ${arr} 0 + defined = is_defined element + assert_false ${defined} + + result = array_set ${arr} 0 10 + assert_false ${result} + + released = release ${arr} + assert ${released} +end