mirror of
https://github.com/sagiegurari/duckscript
synced 2024-10-14 11:53:05 +00:00
New get_by_name command
This commit is contained in:
parent
83f1ce381f
commit
02e99a7a82
|
@ -1,5 +1,9 @@
|
|||
## CHANGELOG
|
||||
|
||||
### v0.3.4
|
||||
|
||||
* New get_by_name command.
|
||||
|
||||
### v0.3.3 (2020-04-15)
|
||||
|
||||
* New which command.
|
||||
|
|
136
docs/sdk.md
136
docs/sdk.md
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
29
duckscript_sdk/src/sdk/std/var/get_by_name/help.md
Normal file
29
duckscript_sdk/src/sdk/std/var/get_by_name/help.md
Normal 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
|
||||
```
|
63
duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs
Executable file
63
duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs
Executable 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(),
|
||||
})
|
||||
}
|
39
duckscript_sdk/src/sdk/std/var/get_by_name/mod_test.rs
Normal file
39
duckscript_sdk/src/sdk/std/var/get_by_name/mod_test.rs
Normal 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()),
|
||||
);
|
||||
}
|
17
duckscript_sdk/src/sdk/std/var/mod.rs
Executable file
17
duckscript_sdk/src/sdk/std/var/mod.rs
Executable 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(())
|
||||
}
|
|
@ -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
|
|
@ -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")
|
24
test/std/var/get_by_name_test.ds
Normal file
24
test/std/var/get_by_name_test.ds
Normal 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
|
||||
|
Loading…
Reference in a new issue