mirror of
https://github.com/sagiegurari/duckscript
synced 2024-10-02 22:24:40 +00:00
New bytes_to_string and string_to_bytes commands.
This commit is contained in:
parent
699acb12ea
commit
b49bf51af6
|
@ -2,6 +2,8 @@
|
|||
|
||||
### v0.1.9
|
||||
|
||||
* New bytes_to_string command.
|
||||
* New string_to_bytes command.
|
||||
* Add prefix flag to write_properties command #77
|
||||
* New split command #76
|
||||
* New appendfile command.
|
||||
|
@ -19,6 +21,7 @@
|
|||
* Improve wget input parsing.
|
||||
* Modify full named commands.
|
||||
* Prevent panic for wget and http_client on invalid non http URL input.
|
||||
* Runtime - Supports byte array state storage
|
||||
|
||||
### v0.1.8 (2020-01-24)
|
||||
|
||||
|
|
64
docs/sdk.md
64
docs/sdk.md
|
@ -66,6 +66,7 @@
|
|||
* [std::process::ProcessID (pid, process_id)](#std__process__ProcessID)
|
||||
* [std::process::Watchdog (watchdog)](#std__process__Watchdog)
|
||||
* [std::scope::Clear (clear_scope)](#std__scope__Clear)
|
||||
* [std::string::BytesToString (bytes_to_string)](#std__string__BytesToString)
|
||||
* [std::string::Concat (concat)](#std__string__Concat)
|
||||
* [std::string::Contains (contains)](#std__string__Contains)
|
||||
* [std::string::EndsWith (ends_with)](#std__string__EndsWith)
|
||||
|
@ -77,6 +78,7 @@
|
|||
* [std::string::Replace (replace)](#std__string__Replace)
|
||||
* [std::string::Split (split)](#std__string__Split)
|
||||
* [std::string::StartsWith (starts_with)](#std__string__StartsWith)
|
||||
* [std::string::StringToBytes (string_to_bytes)](#std__string__StringToBytes)
|
||||
* [std::string::SubString (substring)](#std__string__SubString)
|
||||
* [std::string::Trim (trim)](#std__string__Trim)
|
||||
* [std::string::TrimEnd (trim_end)](#std__string__TrimEnd)
|
||||
|
@ -2502,6 +2504,37 @@ assert_false ${defined}
|
|||
#### Aliases:
|
||||
clear_scope
|
||||
|
||||
<a name="std__string__BytesToString"></a>
|
||||
## std::string::BytesToString
|
||||
```sh
|
||||
text = bytes_to_string handle
|
||||
```
|
||||
|
||||
Converts the provided UTF-8 binary array to string and returns it.
|
||||
|
||||
#### Parameters
|
||||
|
||||
A handle to a binary array holding UTF-8 text.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The textual data.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
handle = string_to_bytes "hello world"
|
||||
text = bytes_to_string ${handle}
|
||||
|
||||
release ${handle}
|
||||
|
||||
assert_eq ${text} "hello world"
|
||||
```
|
||||
|
||||
|
||||
#### Aliases:
|
||||
bytes_to_string
|
||||
|
||||
<a name="std__string__Concat"></a>
|
||||
## std::string::Concat
|
||||
|
||||
|
@ -2867,6 +2900,37 @@ result = starts_with abcd bcd
|
|||
#### Aliases:
|
||||
starts_with
|
||||
|
||||
<a name="std__string__StringToBytes"></a>
|
||||
## std::string::StringToBytes
|
||||
```sh
|
||||
handle = string_to_bytes text
|
||||
```
|
||||
|
||||
Converts the provided string into binary format and returns a handle to the binary data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
The text to convert.
|
||||
|
||||
#### Return Value
|
||||
|
||||
A handle to the binary data.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
handle = string_to_bytes "hello world"
|
||||
text = bytes_to_string ${handle}
|
||||
|
||||
release ${handle}
|
||||
|
||||
assert_eq ${text} "hello world"
|
||||
```
|
||||
|
||||
|
||||
#### Aliases:
|
||||
string_to_bytes
|
||||
|
||||
<a name="std__string__SubString"></a>
|
||||
## std::string::SubString
|
||||
```sh
|
||||
|
|
|
@ -30,6 +30,8 @@ pub enum StateValue {
|
|||
UnsignedNumber64Bit(u64),
|
||||
/// textual value
|
||||
String(String),
|
||||
/// byte (u8) array
|
||||
ByteArray(Vec<u8>),
|
||||
/// list
|
||||
List(Vec<StateValue>),
|
||||
/// sub state value
|
||||
|
|
|
@ -24,6 +24,7 @@ include = [
|
|||
|
||||
[dependencies]
|
||||
attohttpc = "^0.10"
|
||||
base64 = "^0.11"
|
||||
duckscript = { version = "^0.1.7", path = "../duckscript" }
|
||||
fs_extra = "^1"
|
||||
home = "^0.5"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::*;
|
||||
use duckscript::types::command::Commands;
|
||||
use duckscript::runner;
|
||||
use duckscript::types::runtime::Context;
|
||||
|
||||
#[test]
|
||||
fn version_test() {
|
||||
|
@ -10,13 +11,17 @@ fn version_test() {
|
|||
|
||||
#[test]
|
||||
fn load_valid() {
|
||||
let mut commands = Commands::new();
|
||||
let result = load(&mut commands);
|
||||
let mut context = Context::new();
|
||||
let result = load(&mut context.commands);
|
||||
|
||||
match result {
|
||||
Ok(_) => (),
|
||||
Err(e) => panic!("{:#?}", e),
|
||||
};
|
||||
// assert!(result.is_ok());
|
||||
assert!(!commands.get_all_command_names().is_empty());
|
||||
assert!(!context.commands.get_all_command_names().is_empty());
|
||||
|
||||
let result = runner::run_script("test_directory ../test", context);
|
||||
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ impl Command for CommandImpl {
|
|||
CommandResult::Continue(Some(value.to_string()))
|
||||
}
|
||||
StateValue::String(value) => CommandResult::Continue(Some(value)),
|
||||
StateValue::ByteArray(_) => {
|
||||
CommandResult::Error("Unsupported array element.".to_string())
|
||||
}
|
||||
StateValue::List(_) => {
|
||||
CommandResult::Error("Unsupported array element.".to_string())
|
||||
}
|
||||
|
@ -125,6 +128,10 @@ impl Command for CommandImpl {
|
|||
state.insert(key.to_string(), StateValue::String(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
}
|
||||
StateValue::ByteArray(value) => {
|
||||
state.insert(key.to_string(), StateValue::ByteArray(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
}
|
||||
StateValue::SubState(value) => {
|
||||
state.insert(key.to_string(), StateValue::SubState(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
|
|
|
@ -95,6 +95,10 @@ impl Command for CommandImpl {
|
|||
state.insert(key.to_string(), StateValue::String(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
}
|
||||
StateValue::ByteArray(value) => {
|
||||
state.insert(key.to_string(), StateValue::ByteArray(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
}
|
||||
StateValue::SubState(value) => {
|
||||
state.insert(key.to_string(), StateValue::SubState(value));
|
||||
CommandResult::Error("Invalid handle provided.".to_string())
|
||||
|
|
|
@ -248,6 +248,7 @@ fn get_next_iteration(
|
|||
StateValue::Number64Bit(ref value) => Some(value.to_string()),
|
||||
StateValue::UnsignedNumber64Bit(ref value) => Some(value.to_string()),
|
||||
StateValue::String(ref value) => Some(value.to_string()),
|
||||
StateValue::ByteArray(_) => None,
|
||||
StateValue::List(_) => None,
|
||||
StateValue::SubState(_) => None,
|
||||
}
|
||||
|
|
24
duckscript_sdk/src/sdk/std/string/bytes_to_string/help.md
Normal file
24
duckscript_sdk/src/sdk/std/string/bytes_to_string/help.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
```sh
|
||||
text = bytes_to_string handle
|
||||
```
|
||||
|
||||
Converts the provided UTF-8 binary array to string and returns it.
|
||||
|
||||
#### Parameters
|
||||
|
||||
A handle to a binary array holding UTF-8 text.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The textual data.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
handle = string_to_bytes "hello world"
|
||||
text = bytes_to_string ${handle}
|
||||
|
||||
release ${handle}
|
||||
|
||||
assert_eq ${text} "hello world"
|
||||
```
|
76
duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs
Executable file
76
duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs
Executable file
|
@ -0,0 +1,76 @@
|
|||
use crate::utils::pckg;
|
||||
use crate::utils::state::get_handles_sub_state;
|
||||
use duckscript::types::command::{Command, CommandResult, Commands};
|
||||
use duckscript::types::instruction::Instruction;
|
||||
use duckscript::types::runtime::StateValue;
|
||||
use std::collections::HashMap;
|
||||
use std::str;
|
||||
|
||||
#[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, "BytesToString")
|
||||
}
|
||||
|
||||
fn aliases(&self) -> Vec<String> {
|
||||
vec!["bytes_to_string".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.is_empty() {
|
||||
CommandResult::Error("Array handle not provided.".to_string())
|
||||
} else {
|
||||
let state = get_handles_sub_state(state);
|
||||
|
||||
let key = &arguments[0];
|
||||
|
||||
match state.get(key) {
|
||||
Some(state_value) => match state_value {
|
||||
StateValue::ByteArray(binary) => match str::from_utf8(&binary) {
|
||||
Ok(text) => CommandResult::Continue(Some(text.to_string())),
|
||||
Err(error) => CommandResult::Error(error.to_string()),
|
||||
},
|
||||
_ => CommandResult::Error("Invalid handle provided.".to_string()),
|
||||
},
|
||||
None => CommandResult::Error(
|
||||
format!("Array for handle: {} not found.", key).to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create(package: &str) -> Box<dyn Command> {
|
||||
Box::new(CommandImpl {
|
||||
package: package.to_string(),
|
||||
})
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
use super::*;
|
||||
use crate::sdk::std::string::string_to_bytes;
|
||||
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 = bytes_to_string", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_handle_not_found() {
|
||||
test::run_script_and_error(vec![create("")], "out = bytes_to_string badhandle", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_valid() {
|
||||
test::run_script_and_validate(
|
||||
vec![create(""), string_to_bytes::create("")],
|
||||
r#"
|
||||
handle = string_to_bytes "hello world"
|
||||
out = bytes_to_string ${handle}
|
||||
"#,
|
||||
CommandValidation::Match("out".to_string(), "hello world".to_string()),
|
||||
);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
mod bytes_to_string;
|
||||
mod concat;
|
||||
mod contains;
|
||||
mod ends_with;
|
||||
|
@ -9,6 +10,7 @@ mod length;
|
|||
mod replace;
|
||||
mod split;
|
||||
mod starts_with;
|
||||
pub(crate) mod string_to_bytes;
|
||||
mod substring;
|
||||
mod trim;
|
||||
mod trim_end;
|
||||
|
@ -23,6 +25,7 @@ static PACKAGE: &str = "string";
|
|||
pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptError> {
|
||||
let package = pckg::concat(parent, PACKAGE);
|
||||
|
||||
commands.set(bytes_to_string::create(&package))?;
|
||||
commands.set(concat::create(&package)?)?;
|
||||
commands.set(contains::create(&package))?;
|
||||
commands.set(ends_with::create(&package))?;
|
||||
|
@ -34,6 +37,7 @@ pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptEr
|
|||
commands.set(replace::create(&package))?;
|
||||
commands.set(split::create(&package))?;
|
||||
commands.set(starts_with::create(&package))?;
|
||||
commands.set(string_to_bytes::create(&package))?;
|
||||
commands.set(substring::create(&package))?;
|
||||
commands.set(trim::create(&package))?;
|
||||
commands.set(trim_start::create(&package))?;
|
||||
|
|
24
duckscript_sdk/src/sdk/std/string/string_to_bytes/help.md
Normal file
24
duckscript_sdk/src/sdk/std/string/string_to_bytes/help.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
```sh
|
||||
handle = string_to_bytes text
|
||||
```
|
||||
|
||||
Converts the provided string into binary format and returns a handle to the binary data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
The text to convert.
|
||||
|
||||
#### Return Value
|
||||
|
||||
A handle to the binary data.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
handle = string_to_bytes "hello world"
|
||||
text = bytes_to_string ${handle}
|
||||
|
||||
release ${handle}
|
||||
|
||||
assert_eq ${text} "hello world"
|
||||
```
|
64
duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs
Executable file
64
duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs
Executable file
|
@ -0,0 +1,64 @@
|
|||
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, "StringToBytes")
|
||||
}
|
||||
|
||||
fn aliases(&self) -> Vec<String> {
|
||||
vec!["string_to_bytes".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.is_empty() {
|
||||
CommandResult::Error("Missing input.".to_string())
|
||||
} else {
|
||||
let array = arguments[0].clone().into_bytes();
|
||||
|
||||
let key = put_handle(state, StateValue::ByteArray(array));
|
||||
|
||||
CommandResult::Continue(Some(key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create(package: &str) -> Box<dyn Command> {
|
||||
Box::new(CommandImpl {
|
||||
package: package.to_string(),
|
||||
})
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
use super::*;
|
||||
use crate::test;
|
||||
use crate::test::CommandValidation;
|
||||
use crate::utils::state::get_handles_sub_state;
|
||||
use std::str;
|
||||
|
||||
#[test]
|
||||
fn common_functions() {
|
||||
test::test_common_command_functions(create(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_no_args() {
|
||||
test::run_script_and_error(vec![create("")], "out = string_to_bytes", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_valid() {
|
||||
let mut context = test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
r#"out = string_to_bytes "hello world""#,
|
||||
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::ByteArray(binary) => {
|
||||
let text = str::from_utf8(&binary).unwrap();
|
||||
assert_eq!(text, "hello world");
|
||||
}
|
||||
_ => panic!("Invalid type."),
|
||||
}
|
||||
}
|
9
test/std/string/binary_test.ds
Normal file
9
test/std/string/binary_test.ds
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
function test_binary_string
|
||||
handle = string_to_bytes "hello world"
|
||||
text = bytes_to_string ${handle}
|
||||
|
||||
release ${handle}
|
||||
|
||||
assert_eq ${text} "hello world"
|
||||
end
|
Loading…
Reference in a new issue