New split command #76

This commit is contained in:
sagie gur ari 2020-01-30 21:10:36 +00:00
parent 8e463dd635
commit cf2411dbd8
8 changed files with 285 additions and 0 deletions

View file

@ -2,6 +2,7 @@
### v0.1.9
* New split command #76
* New appendfile command.
* New watchdog command.
* New pid command #73

View file

@ -75,6 +75,7 @@
* [std::string::LastIndexOf (last_indexof)](#std__string__LastIndexOf)
* [std::string::Length (length, strlen)](#std__string__Length)
* [std::string::Replace (replace)](#std__string__Replace)
* [std::string::Split (split)](#std__string__Split)
* [std::string::StartsWith (starts_with)](#std__string__StartsWith)
* [std::string::SubString (substring)](#std__string__SubString)
* [std::string::Trim (trim)](#std__string__Trim)
@ -2780,6 +2781,51 @@ assert_eq ${updated} "my large stuff value with lots of stuff"
#### Aliases:
replace
<a name="std__string__Split"></a>
## std::string::Split
```sh
handle = split text pattern
```
Splits the provided text based on the provided pattern and return a handle the
created array with all the splitted values.
#### Parameters
* The text to split
* The pattern to split by
#### Return Value
A handle to the values array.
#### Examples
```sh
handle = split a23b23c23d23e 23
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} e
value = array_pop ${handle}
assert_eq ${value} d
value = array_pop ${handle}
assert_eq ${value} c
value = array_pop ${handle}
assert_eq ${value} b
value = array_pop ${handle}
assert_eq ${value} a
release ${handle}
assert_eq ${len} 5
```
#### Aliases:
split
<a name="std__string__StartsWith"></a>
## std::string::StartsWith
```sh

View file

@ -7,6 +7,7 @@ mod is_empty;
mod last_indexof;
mod length;
mod replace;
mod split;
mod starts_with;
mod substring;
mod trim;
@ -31,6 +32,7 @@ pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptEr
commands.set(last_indexof::create(&package))?;
commands.set(length::create(&package))?;
commands.set(replace::create(&package))?;
commands.set(split::create(&package))?;
commands.set(starts_with::create(&package))?;
commands.set(substring::create(&package))?;
commands.set(trim::create(&package))?;

View file

@ -0,0 +1,38 @@
```sh
handle = split text pattern
```
Splits the provided text based on the provided pattern and return a handle the
created array with all the splitted values.
#### Parameters
* The text to split
* The pattern to split by
#### Return Value
A handle to the values array.
#### Examples
```sh
handle = split a23b23c23d23e 23
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} e
value = array_pop ${handle}
assert_eq ${value} d
value = array_pop ${handle}
assert_eq ${value} c
value = array_pop ${handle}
assert_eq ${value} b
value = array_pop ${handle}
assert_eq ${value} a
release ${handle}
assert_eq ${len} 5
```

View file

@ -0,0 +1,70 @@
use crate::utils::pckg;
use crate::utils::state::put_handle;
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, "Split")
}
fn aliases(&self) -> Vec<String> {
vec!["split".to_string()]
}
fn help(&self) -> String {
include_str!("help.md").to_string()
}
fn clone_and_box(&self) -> Box<dyn Command> {
Box::new((*self).clone())
}
fn requires_context(&self) -> bool {
true
}
fn run_with_context(
&self,
arguments: Vec<String>,
state: &mut HashMap<String, StateValue>,
_variables: &mut HashMap<String, String>,
_output_variable: Option<String>,
_instructions: &Vec<Instruction>,
_commands: &mut Commands,
_line: usize,
) -> CommandResult {
if arguments.len() < 2 {
CommandResult::Error("Invalid input provided.".to_string())
} else {
let split = arguments[0].split(&arguments[1]);
let values = split.collect::<Vec<&str>>();
let mut array = vec![];
for value in values {
array.push(StateValue::String(value.to_string()));
}
let key = put_handle(state, StateValue::List(array));
CommandResult::Continue(Some(key))
}
}
}
pub(crate) fn create(package: &str) -> Box<dyn Command> {
Box::new(CommandImpl {
package: package.to_string(),
})
}

View file

@ -0,0 +1,52 @@
use super::*;
use crate::test;
use crate::test::CommandValidation;
use crate::utils::state::get_handles_sub_state;
#[test]
fn common_functions() {
test::test_common_command_functions(create(""));
}
#[test]
fn run_no_args() {
test::run_script_and_error(vec![create("")], "out = split", "out");
}
#[test]
fn run_single_arg() {
test::run_script_and_error(vec![create("")], "out = split abc", "out");
}
#[test]
fn run_split() {
let mut context = test::run_script_and_validate(
vec![create("")],
r#"out = split "a b c" " ""#,
CommandValidation::Ignore,
);
let state = get_handles_sub_state(&mut context.state);
let list_value = state.remove(context.variables.get("out").unwrap()).unwrap();
match list_value {
StateValue::List(mut list) => {
assert_eq!(list.len(), 3);
match list.pop().unwrap() {
StateValue::String(value) => assert_eq!(value, "c"),
_ => panic!("Invalid handle value."),
};
match list.pop().unwrap() {
StateValue::String(value) => assert_eq!(value, "b"),
_ => panic!("Invalid handle value."),
};
match list.pop().unwrap() {
StateValue::String(value) => assert_eq!(value, "a"),
_ => panic!("Invalid handle value."),
};
}
_ => panic!("Invalid type."),
}
}

View file

@ -168,6 +168,7 @@ pub(crate) enum CommandValidation {
Match(String, String),
Contains(String, String),
Any(String, Vec<String>),
Ignore,
}
pub(crate) fn test_common_command_functions(command: Box<dyn Command>) {
@ -269,6 +270,9 @@ pub(crate) fn run_script_and_validate(
let numeric_value: u128 = var_value.parse().unwrap();
assert!(numeric_value > 0)
}
CommandValidation::Ignore => {
assert!(!context.variables.is_empty());
}
};
context

View file

@ -0,0 +1,72 @@
function test_empty_string
handle = split "" \n
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} ""
release ${handle}
assert_eq ${len} 1
end
function test_not_found
handle = split 12345 6
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} 12345
release ${handle}
assert_eq ${len} 1
end
function test_found
handle = split a23b23c23d23e 23
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} e
value = array_pop ${handle}
assert_eq ${value} d
value = array_pop ${handle}
assert_eq ${value} c
value = array_pop ${handle}
assert_eq ${value} b
value = array_pop ${handle}
assert_eq ${value} a
release ${handle}
assert_eq ${len} 5
end
function test_found_at_start_and_end
handle = split 23a23b23c23d23e23 23
len = array_length ${handle}
value = array_pop ${handle}
assert_eq ${value} ""
value = array_pop ${handle}
assert_eq ${value} e
value = array_pop ${handle}
assert_eq ${value} d
value = array_pop ${handle}
assert_eq ${value} c
value = array_pop ${handle}
assert_eq ${value} b
value = array_pop ${handle}
assert_eq ${value} a
value = array_pop ${handle}
assert_eq ${value} ""
release ${handle}
assert_eq ${len} 7
end