mirror of
https://github.com/sagiegurari/duckscript
synced 2024-11-05 16:09:58 +00:00
New --collection flag to json_parse command which returns maps/arrays instead of variables #175
This commit is contained in:
parent
dd760cfb50
commit
540e556908
6 changed files with 144 additions and 12 deletions
|
@ -1,5 +1,9 @@
|
|||
## CHANGELOG
|
||||
|
||||
### v0.8.4
|
||||
|
||||
* New --collection flag to json_parse command which returns maps/arrays instead of variables #175
|
||||
|
||||
### v0.8.3
|
||||
|
||||
* Fix release with recursive flag to support set data structures as well.
|
||||
|
|
28
docs/sdk.md
28
docs/sdk.md
|
@ -4142,17 +4142,22 @@ root.child[5]
|
|||
root.child.length
|
||||
```
|
||||
|
||||
In case the --collection flag is provided, it will instead create maps/array as needed and return the root handle (or primitive value) of
|
||||
the json data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
The JSON string to parse.
|
||||
* Optional --collection flag to parse and return value/map/array
|
||||
* The JSON string to parse.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The root value.
|
||||
The root value/handle.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
# parse to simple variables
|
||||
package = json_parse "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
|
||||
assert_eq ${package} "[OBJECT]"
|
||||
|
@ -4163,6 +4168,25 @@ assert_eq ${package.keywords.length} 2
|
|||
assert_eq ${package.keywords[0]} test1
|
||||
assert_eq ${package.keywords[1]} test2
|
||||
assert_eq ${package.directories.test} spec
|
||||
|
||||
# parse to maps/arrays
|
||||
package = json_parse --collection "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
name = map_get ${package} name
|
||||
assert_eq ${name} "my package"
|
||||
version = map_get ${package} version
|
||||
assert_eq ${version} 1
|
||||
public = map_get ${package} public
|
||||
assert_false ${public}
|
||||
keywords_handle = map_get ${package} keywords
|
||||
length = array_length ${keywords_handle}
|
||||
assert_eq ${length} 2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test1
|
||||
directories = map_get ${package} directories
|
||||
directory = map_get ${directories} test
|
||||
assert_eq ${directory} spec
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -12,17 +12,22 @@ root.child[5]
|
|||
root.child.length
|
||||
```
|
||||
|
||||
In case the --collection flag is provided, it will instead create maps/array as needed and return the root handle (or primitive value) of
|
||||
the json data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
The JSON string to parse.
|
||||
* Optional --collection flag to parse and return value/map/array
|
||||
* The JSON string to parse.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The root value.
|
||||
The root value/handle.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
# parse to simple variables
|
||||
package = json_parse "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
|
||||
assert_eq ${package} "[OBJECT]"
|
||||
|
@ -33,4 +38,23 @@ assert_eq ${package.keywords.length} 2
|
|||
assert_eq ${package.keywords[0]} test1
|
||||
assert_eq ${package.keywords[1]} test2
|
||||
assert_eq ${package.directories.test} spec
|
||||
|
||||
# parse to maps/arrays
|
||||
package = json_parse --collection "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
name = map_get ${package} name
|
||||
assert_eq ${name} "my package"
|
||||
version = map_get ${package} version
|
||||
assert_eq ${version} 1
|
||||
public = map_get ${package} public
|
||||
assert_false ${public}
|
||||
keywords_handle = map_get ${package} keywords
|
||||
length = array_length ${keywords_handle}
|
||||
assert_eq ${length} 2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test1
|
||||
directories = map_get ${package} directories
|
||||
directory = map_get ${directories} test
|
||||
assert_eq ${directory} spec
|
||||
```
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::sdk::std::json::OBJECT_VALUE;
|
||||
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;
|
||||
|
@ -46,6 +47,41 @@ fn create_variables(data: Value, name: &str, variables: &mut HashMap<String, Str
|
|||
};
|
||||
}
|
||||
|
||||
fn create_structure(data: Value, state: &mut HashMap<String, StateValue>) -> Option<String> {
|
||||
match data {
|
||||
Value::Null => None,
|
||||
Value::Bool(value) => Some(value.to_string()),
|
||||
Value::Number(value) => Some(value.to_string()),
|
||||
Value::String(value) => Some(value),
|
||||
Value::Array(list) => {
|
||||
let mut state_list = vec![];
|
||||
|
||||
for item in list {
|
||||
if let Some(value) = create_structure(item, state) {
|
||||
state_list.push(StateValue::String(value));
|
||||
}
|
||||
}
|
||||
|
||||
let key = put_handle(state, StateValue::List(state_list));
|
||||
|
||||
Some(key)
|
||||
}
|
||||
Value::Object(map) => {
|
||||
let mut state_map = HashMap::new();
|
||||
|
||||
for (key, value) in map {
|
||||
if let Some(value) = create_structure(value, state) {
|
||||
state_map.insert(key, StateValue::String(value));
|
||||
}
|
||||
}
|
||||
|
||||
let key = put_handle(state, StateValue::SubState(state_map));
|
||||
|
||||
Some(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CommandImpl {
|
||||
package: String,
|
||||
|
@ -75,7 +111,7 @@ impl Command for CommandImpl {
|
|||
fn run_with_context(
|
||||
&self,
|
||||
arguments: Vec<String>,
|
||||
_state: &mut HashMap<String, StateValue>,
|
||||
state: &mut HashMap<String, StateValue>,
|
||||
variables: &mut HashMap<String, String>,
|
||||
output_variable: Option<String>,
|
||||
_instructions: &Vec<Instruction>,
|
||||
|
@ -85,15 +121,25 @@ impl Command for CommandImpl {
|
|||
if arguments.is_empty() {
|
||||
CommandResult::Error("No JSON string provided.".to_string())
|
||||
} else {
|
||||
match parse_json(&arguments[0]) {
|
||||
let (json_index, as_state) = if arguments.len() > 1 && arguments[0] == "--collection" {
|
||||
(1, true)
|
||||
} else {
|
||||
(0, false)
|
||||
};
|
||||
|
||||
match parse_json(&arguments[json_index]) {
|
||||
Ok(data) => {
|
||||
let output = match output_variable {
|
||||
Some(name) => {
|
||||
create_variables(data, &name, variables);
|
||||
if as_state {
|
||||
create_structure(data, state)
|
||||
} else {
|
||||
create_variables(data, &name, variables);
|
||||
|
||||
match variables.get(&name) {
|
||||
Some(value) => Some(value.to_string()),
|
||||
None => None,
|
||||
match variables.get(&name) {
|
||||
Some(value) => Some(value.to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
None => Some("true".to_string()),
|
||||
|
|
|
@ -13,7 +13,7 @@ fn run_no_args() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn run_all_types() {
|
||||
fn run_all_types_as_vars() {
|
||||
let context = test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
r#"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
fn test_all_types
|
||||
fn test_all_types_as_vars
|
||||
package = json_parse "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
|
||||
assert_eq ${package} "[OBJECT]"
|
||||
|
@ -12,3 +12,37 @@ fn test_all_types
|
|||
assert_eq ${package.directories.test} spec
|
||||
end
|
||||
|
||||
fn test_all_types_as_collections
|
||||
package = json_parse --collection "{\"name\": \"my package\", \"version\": 1, \"publish\": false, \"keywords\": [\"test1\", \"test2\"], \"directories\": {\"test\": \"spec\"}}"
|
||||
|
||||
output = is_map ${package}
|
||||
assert ${output}
|
||||
|
||||
name = map_get ${package} name
|
||||
assert_eq ${name} "my package"
|
||||
|
||||
version = map_get ${package} version
|
||||
assert_eq ${version} 1
|
||||
|
||||
public = map_get ${package} public
|
||||
assert_false ${public}
|
||||
|
||||
keywords_handle = map_get ${package} keywords
|
||||
output = is_array ${keywords_handle}
|
||||
assert ${output}
|
||||
|
||||
length = array_length ${keywords_handle}
|
||||
assert_eq ${length} 2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test2
|
||||
value = array_pop ${keywords_handle}
|
||||
assert_eq ${value} test1
|
||||
|
||||
directories = map_get ${package} directories
|
||||
output = is_map ${directories}
|
||||
assert ${output}
|
||||
|
||||
directory = map_get ${directories} test
|
||||
assert_eq ${directory} spec
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue