New get_by_name command

This commit is contained in:
sagie gur ari 2020-05-02 11:24:54 +00:00
parent 83f1ce381f
commit 02e99a7a82
13 changed files with 270 additions and 59 deletions

View file

@ -1,5 +1,9 @@
## CHANGELOG
### v0.3.4
* New get_by_name command.
### v0.3.3 (2020-04-15)
* New which command.

View file

@ -5,7 +5,6 @@
* [std::Not (not)](#std__Not)
* [std::ReadUserInput (read)](#std__ReadUserInput)
* [std::Release (release)](#std__Release)
* [std::Set (set)](#std__Set)
* [std::ShowCommandDocumentation (man)](#std__ShowCommandDocumentation)
* [std::collections::Array (array)](#std__collections__Array)
* [std::collections::ArrayConcat (array_concat)](#std__collections__ArrayConcat)
@ -131,6 +130,8 @@
* [std::test::TestDirectory (test_directory)](#std__test__TestDirectory)
* [std::thread::Sleep (sleep)](#std__thread__Sleep)
* [std::time::CurrentTimeMillies (current_time)](#std__time__CurrentTimeMillies)
* [std::var::GetByName (get_by_name)](#std__var__GetByName)
* [std::var::Set (set)](#std__var__Set)
<a name="std__Echo"></a>
@ -363,51 +364,6 @@ release ${array_handle}
#### Aliases:
release
<a name="std__Set"></a>
## std::Set
```sh
var = set arg [or arg]*
```
The set command will simply return the provided argument and set it to the output variable.<br>
In case the argument is falsy it will attempt to provide another value if an 'or' keyword is set.
A value is considered falsy if it is one of the following:
* false (case insensitive)
* 0
* no (case insensitive)
* Empty value
#### Parameters
The argument to set or an 'or' conditional arguments.
#### Return Value
The first truthy value
#### Examples
```sh
# Return simple 'hello' text value
var = set hello
# Return expanded value: 'home: ....'
var = set "home: ${HOME}"
value = set test or false
assert_eq ${value} test
value = set 0 or no or false or NO or FALSE
assert_eq ${value} FALSE
```
#### Aliases:
set
<a name="std__ShowCommandDocumentation"></a>
## std::ShowCommandDocumentation
```sh
@ -2252,7 +2208,7 @@ When a function command is detected, it will search for the end command that com
That entire block is considered the function code block (functions cannot be nested in outer functions)<br>
In order to invoke the function, simply call the function name with any amount of paramters.<br>
Those parameters will be set as $1, $2, ... and so on.<br>
Those parameters will be set as ${1}, ${2}, ... and so on.<br>
Since variables are global, it will overwrite any older values stored in those variables.<br>
To exist a function and return a value, simply use the **return** command with the value you want to return.<br>
@ -2265,7 +2221,7 @@ In case the code reached the **end** call, the function will exist but will retu
* function - The function name used later on to invoke the function
* end - no parameters
* return - optional single paramter to return as an output of the function call
* *function name* - Any number of arguments which will automatically be set as global variables: $1, $2, ... as so on.
* *function name* - Any number of arguments which will automatically be set as global variables: ${1}, ${2}, ... as so on.
#### Return Value
@ -2297,8 +2253,8 @@ echo ${text}
# Example of passing arguments
fn print_input
# $1 is set with the value 'hello'
# $2 is set with the value 'world'
# ${1} is set with the value 'hello'
# ${2} is set with the value 'world'
echo ${1} ${2}
end
@ -4795,6 +4751,86 @@ echo ${result}
#### Aliases:
current_time
<a name="std__var__GetByName"></a>
## std::var::GetByName
```sh
var = get_by_name name
```
This command returns the variable value based on the given variable name.<br>
It is similar to
```sh
var = set ${name}
```
However, it allows for a dynamic variable name.
#### Parameters
The variable name.
#### Return Value
The variable value or none if no such variable exists.
#### Examples
```sh
var = set test
value = get_by_name var
defined = is_defined value
assert ${defined}
assert_eq ${value} test
```
#### Aliases:
get_by_name
<a name="std__var__Set"></a>
## std::var::Set
```sh
var = set arg [or arg]*
```
The set command will simply return the provided argument and set it to the output variable.<br>
In case the argument is falsy it will attempt to provide another value if an 'or' keyword is set.
A value is considered falsy if it is one of the following:
* false (case insensitive)
* 0
* no (case insensitive)
* Empty value
#### Parameters
The argument to set or an 'or' conditional arguments.
#### Return Value
The first truthy value
#### Examples
```sh
# Return simple 'hello' text value
var = set hello
# Return expanded value: 'home: ....'
var = set "home: ${HOME}"
value = set test or false
assert_eq ${value} test
value = set 0 or no or false or NO or FALSE
assert_eq ${value} FALSE
```
#### Aliases:
set
### License
Developed by Sagie Gur-Ari and licensed under the
[Apache 2](https://github.com/sagiegurari/duckscript/blob/master/LICENSE) open source license.

View file

@ -1,6 +1,6 @@
use super::*;
use crate::sdk::std::collections::{map, map_put};
use crate::sdk::std::set;
use crate::sdk::std::var::set;
use crate::test;
use crate::test::CommandValidation;

View file

@ -16,11 +16,11 @@ mod process;
mod read;
pub(crate) mod release;
pub(crate) mod scope;
pub(crate) mod set;
pub(crate) mod string;
mod test;
mod thread;
mod time;
mod var;
use duckscript::types::command::Commands;
use duckscript::types::error::ScriptError;
@ -35,7 +35,6 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> {
commands.set(not::create(PACKAGE))?;
commands.set(read::create(PACKAGE))?;
commands.set(release::create(PACKAGE))?;
commands.set(set::create(PACKAGE))?;
collections::load(commands, PACKAGE)?;
debug::load(commands, PACKAGE)?;
@ -52,6 +51,7 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> {
test::load(commands, PACKAGE)?;
thread::load(commands, PACKAGE)?;
time::load(commands, PACKAGE)?;
var::load(commands, PACKAGE)?;
Ok(())
}

View file

@ -0,0 +1,29 @@
```sh
var = get_by_name name
```
This command returns the variable value based on the given variable name.<br>
It is similar to
```sh
var = set ${name}
```
However, it allows for a dynamic variable name.
#### Parameters
The variable name.
#### Return Value
The variable value or none if no such variable exists.
#### Examples
```sh
var = set test
value = get_by_name var
defined = is_defined value
assert ${defined}
assert_eq ${value} test
```

View file

@ -0,0 +1,63 @@
use crate::utils::pckg;
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, "GetByName")
}
fn aliases(&self) -> Vec<String> {
vec!["get_by_name".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 {
let output = if arguments.is_empty() {
None
} else {
match variables.get(&arguments[0]) {
Some(ref value) => Some(value.to_string()),
None => None,
}
};
CommandResult::Continue(output)
}
}
pub(crate) fn create(package: &str) -> Box<dyn Command> {
Box::new(CommandImpl {
package: package.to_string(),
})
}

View file

@ -0,0 +1,39 @@
use super::*;
use crate::sdk::std::var::set;
use crate::test;
use crate::test::CommandValidation;
#[test]
fn common_functions() {
test::test_common_command_functions(create(""));
}
#[test]
fn run_no_arguments() {
test::run_script_and_validate(
vec![create("")],
"out = get_by_name",
CommandValidation::None,
);
}
#[test]
fn run_variable_not_found() {
test::run_script_and_validate(
vec![create("")],
"out = get_by_name test",
CommandValidation::None,
);
}
#[test]
fn run_variable_found() {
test::run_script_and_validate(
vec![create(""), set::create("")],
r#"
test = set value
out = get_by_name test
"#,
CommandValidation::Match("out".to_string(), "value".to_string()),
);
}

View file

@ -0,0 +1,17 @@
mod get_by_name;
pub(crate) mod set;
use crate::utils::pckg;
use duckscript::types::command::Commands;
use duckscript::types::error::ScriptError;
static PACKAGE: &str = "var";
pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptError> {
let package = pckg::concat(parent, PACKAGE);
commands.set(get_by_name::create(&package))?;
commands.set(set::create(&package))?;
Ok(())
}

View file

@ -16,7 +16,6 @@ A value is considered falsy if it is one of the following:
The argument to set or an 'or' conditional arguments.
#### Return Value
The first truthy value

View file

@ -5,11 +5,6 @@ use duckscript::types::command::{Command, CommandResult};
#[path = "./mod_test.rs"]
mod mod_test;
#[derive(Clone)]
pub(crate) struct CommandImpl {
package: String,
}
fn get_output(arguments: &Vec<String>) -> Result<Option<String>, String> {
let mut looking_for_value = true;
let mut last_value = None;
@ -36,6 +31,11 @@ fn get_output(arguments: &Vec<String>) -> Result<Option<String>, String> {
}
}
#[derive(Clone)]
pub(crate) struct CommandImpl {
package: String,
}
impl Command for CommandImpl {
fn name(&self) -> String {
pckg::concat(&self.package, "Set")

View file

@ -0,0 +1,24 @@
fn test_no_name
value = get_by_name
defined = is_defined value
assert_false ${defined}
end
fn test_variable_not_found
value = get_by_name notfound
defined = is_defined value
assert_false ${defined}
end
fn test_variable_found
var = set test
value = get_by_name var
defined = is_defined value
assert ${defined}
assert_eq ${value} test
end