From 8acbcd750b7ae3e8c0bb4b61407fc6c1d56119e2 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Sat, 31 Aug 2024 16:16:10 +0000 Subject: [PATCH] Enhancement: Runtime - [Breaking Change] New Env struct enabling commands to redirect out/err to provided streams #440 --- CHANGELOG.md | 4 + docs/_includes/content.md | 8 +- duckscript/src/runner.rs | 43 +++++--- duckscript/src/runner_test.rs | 98 ++++++++++++++----- duckscript/src/test/mod.rs | 4 + duckscript/src/types/command.rs | 3 + duckscript/src/types/command_test.rs | 2 + duckscript/src/types/env.rs | 42 ++++++++ duckscript/src/types/env_test.rs | 26 +++++ duckscript/src/types/mod.rs | 1 + duckscript/src/types/runtime.rs | 9 +- duckscript/src/types/runtime_test.rs | 18 +++- duckscript_cli/src/main.rs | 4 +- duckscript_sdk/src/lib_test.rs | 1 + .../src/sdk/internal/sdkdocs/mod.rs | 6 +- .../src/sdk/std/collections/array/mod.rs | 2 + .../sdk/std/collections/array_clear/mod.rs | 2 + .../src/sdk/std/collections/array_get/mod.rs | 2 + .../sdk/std/collections/array_length/mod.rs | 2 + .../src/sdk/std/collections/array_pop/mod.rs | 2 + .../src/sdk/std/collections/array_push/mod.rs | 2 + .../sdk/std/collections/array_remove/mod.rs | 2 + .../src/sdk/std/collections/array_set/mod.rs | 2 + .../src/sdk/std/collections/is_array/mod.rs | 2 + .../src/sdk/std/collections/is_map/mod.rs | 2 + .../src/sdk/std/collections/is_set/mod.rs | 2 + .../src/sdk/std/collections/map/mod.rs | 2 + .../src/sdk/std/collections/map_clear/mod.rs | 2 + .../src/sdk/std/collections/map_get/mod.rs | 2 + .../src/sdk/std/collections/map_keys/mod.rs | 2 + .../collections/map_load_properties/mod.rs | 2 + .../src/sdk/std/collections/map_put/mod.rs | 2 + .../src/sdk/std/collections/map_remove/mod.rs | 2 + .../src/sdk/std/collections/map_size/mod.rs | 2 + .../std/collections/map_to_properties/mod.rs | 2 + .../src/sdk/std/collections/range/mod.rs | 2 + .../std/collections/read_properties/mod.rs | 2 + .../src/sdk/std/collections/set/mod.rs | 2 + .../src/sdk/std/collections/set_clear/mod.rs | 2 + .../sdk/std/collections/set_contains/mod.rs | 2 + .../src/sdk/std/collections/set_put/mod.rs | 2 + .../src/sdk/std/collections/set_remove/mod.rs | 2 + .../src/sdk/std/collections/set_size/mod.rs | 2 + .../sdk/std/collections/set_to_array/mod.rs | 2 + .../std/collections/write_properties/mod.rs | 2 + .../sdk/std/debug/dump_instructions/mod.rs | 9 +- .../src/sdk/std/debug/dump_state/mod.rs | 7 +- .../src/sdk/std/debug/dump_variables/mod.rs | 7 +- duckscript_sdk/src/sdk/std/echo/mod.rs | 33 +++++-- .../src/sdk/std/env/env_to_map/mod.rs | 2 + .../std/env/print_current_directory/mod.rs | 28 +++++- duckscript_sdk/src/sdk/std/env/set_env/mod.rs | 2 + duckscript_sdk/src/sdk/std/eval/mod.rs | 4 +- .../src/sdk/std/flowcontrol/end/mod.rs | 3 + .../src/sdk/std/flowcontrol/forin/mod.rs | 3 + .../src/sdk/std/flowcontrol/function/mod.rs | 5 + .../src/sdk/std/flowcontrol/ifelse/mod.rs | 7 +- .../src/sdk/std/flowcontrol/while_mod/mod.rs | 4 + .../sdk/std/fs/gitignore_path_array/mod.rs | 2 + .../src/sdk/std/fs/glob_array/mod.rs | 2 + duckscript_sdk/src/sdk/std/fs/list/mod.rs | 40 ++++++-- duckscript_sdk/src/sdk/std/fs/print/mod.rs | 28 +++++- .../src/sdk/std/fs/read_bytes/mod.rs | 2 + .../src/sdk/std/fs/write_bytes/mod.rs | 2 + duckscript_sdk/src/sdk/std/fs/zip/zip/mod.rs | 2 + .../src/sdk/std/is_command_defined/mod.rs | 2 + duckscript_sdk/src/sdk/std/json/encode/mod.rs | 2 + duckscript_sdk/src/sdk/std/json/parse/mod.rs | 2 + .../src/sdk/std/lib/alias/set/mod.rs | 5 +- .../src/sdk/std/lib/alias/unset/mod.rs | 2 + .../src/sdk/std/lib/command/remove/mod.rs | 2 + duckscript_sdk/src/sdk/std/man/mod.rs | 16 +-- .../src/sdk/std/net/ftp/get_in_memory/mod.rs | 2 + .../src/sdk/std/net/ftp/list/mod.rs | 2 + .../src/sdk/std/net/ftp/nlst/mod.rs | 2 + duckscript_sdk/src/sdk/std/not/mod.rs | 11 ++- .../src/sdk/std/on_error/exit_on_error/mod.rs | 2 + .../sdk/std/on_error/get_last_error/mod.rs | 2 + .../std/on_error/get_last_error_line/mod.rs | 2 + .../std/on_error/get_last_error_source/mod.rs | 2 + .../src/sdk/std/on_error/on_error/mod.rs | 2 + .../src/sdk/std/on_error/set_error/mod.rs | 2 + duckscript_sdk/src/sdk/std/print/mod.rs | 33 +++++-- duckscript_sdk/src/sdk/std/println/mod.rs | 36 +++++-- .../src/sdk/std/process/exec/mod.rs | 2 + duckscript_sdk/src/sdk/std/release/mod.rs | 2 + duckscript_sdk/src/sdk/std/scope/clear/mod.rs | 2 + .../src/sdk/std/scope/pop_stack/mod.rs | 2 + .../src/sdk/std/scope/push_stack/mod.rs | 2 + .../src/sdk/std/semver/parse/mod.rs | 2 + .../src/sdk/std/string/base64_decode/mod.rs | 2 + .../src/sdk/std/string/base64_encode/mod.rs | 2 + .../src/sdk/std/string/bytes_to_string/mod.rs | 2 + .../src/sdk/std/string/split/mod.rs | 2 + .../src/sdk/std/string/string_to_bytes/mod.rs | 2 + .../src/sdk/std/test/test_directory/mod.rs | 4 +- .../src/sdk/std/test/test_file/mod.rs | 18 +++- .../src/sdk/std/var/get_all_var_names/mod.rs | 2 + .../src/sdk/std/var/get_by_name/mod.rs | 2 + .../src/sdk/std/var/is_defined/mod.rs | 2 + .../src/sdk/std/var/set_by_name/mod.rs | 2 + .../src/sdk/std/var/unset_all_vars/mod.rs | 2 + duckscript_sdk/src/test/mod.rs | 6 +- duckscript_sdk/src/types/command.rs | 4 +- duckscript_sdk/src/utils/condition.rs | 12 ++- duckscript_sdk/src/utils/condition_test.rs | 6 ++ duckscript_sdk/src/utils/eval.rs | 20 +++- duckscript_sdk/src/utils/eval_test.rs | 20 ++++ test/std/fs/gitignore_path_array_test.ds | 2 +- 109 files changed, 663 insertions(+), 111 deletions(-) create mode 100644 duckscript/src/types/env.rs create mode 100644 duckscript/src/types/env_test.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index f07a6782..f1b439da 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## CHANGELOG +### v0.10.0 + +* Enhancement: Runtime - \[Breaking Change\] New Env struct enabling commands to redirect out/err to provided streams #440 + ### v0.9.3 (2024-01-19) * Fix: if/else condition with a command that accepts empty values #390 diff --git a/docs/_includes/content.md b/docs/_includes/content.md index 3784fcdf..ca756b2b 100755 --- a/docs/_includes/content.md +++ b/docs/_includes/content.md @@ -457,6 +457,7 @@ The run_with_context signature is as follows: /// * `instructions` - The entire list of instructions which make up the currently running script /// * `commands` - The currently known commands /// * `line` - The current instruction line number (global line number after including all scripts into one global script) +/// * `env` - The current runtime env with access to out/err writers, etc... fn run_with_context( &self, arguments: Vec, @@ -466,6 +467,7 @@ fn run_with_context( instructions: &Vec, commands: &mut Commands, line: usize, + env: &mut Env, ) -> CommandResult; ``` @@ -479,7 +481,7 @@ The duckscript cli basically embeds duckscript so you can look at it as a refere ```rust let mut context = Context::new(); duckscriptsdk::load(&mut context.commands)?; -runner::run_script_file(file, context)?; +runner::run_script_file(file, context, None)?; ``` That's it!
@@ -502,10 +504,10 @@ The following public functions are available: ```rust /// Executes the provided script with the given context -pub fn run_script(text: &str, context: Context) -> Result; +pub fn run_script(text: &str, context: Context, env: Option) -> Result; /// Executes the provided script file with the given context -pub fn run_script_file(file: &str, context: Context) -> Result; +pub fn run_script_file(file: &str, context: Context, env: Option) -> Result; ``` diff --git a/duckscript/src/runner.rs b/duckscript/src/runner.rs index 495c755b..2b9c2ba0 100644 --- a/duckscript/src/runner.rs +++ b/duckscript/src/runner.rs @@ -10,6 +10,7 @@ mod runner_test; use crate::expansion::{self, ExpandedValue}; use crate::parser; use crate::types::command::{CommandResult, Commands, GoToValue}; +use crate::types::env::Env; use crate::types::error::ScriptError; use crate::types::instruction::{ Instruction, InstructionMetaInfo, InstructionType, ScriptInstruction, @@ -26,17 +27,21 @@ enum EndReason { } /// Executes the provided script with the given context -pub fn run_script(text: &str, context: Context) -> Result { +pub fn run_script(text: &str, context: Context, env: Option) -> Result { match parser::parse_text(text) { - Ok(instructions) => run(instructions, context), + Ok(instructions) => run(instructions, context, env), Err(error) => Err(error), } } /// Executes the provided script file with the given context -pub fn run_script_file(file: &str, context: Context) -> Result { +pub fn run_script_file( + file: &str, + context: Context, + env: Option, +) -> Result { match parser::parse_file(file) { - Ok(instructions) => run(instructions, context), + Ok(instructions) => run(instructions, context, env), Err(error) => Err(error), } } @@ -58,7 +63,7 @@ pub fn repl(mut context: Context) -> Result { // add new instructions instructions.append(&mut new_instructions); - let runtime = create_runtime(instructions.clone(), context); + let runtime = create_runtime(instructions.clone(), context, None); let (updated_context, end_reason) = run_instructions(runtime, start, true)?; @@ -83,8 +88,12 @@ pub fn repl(mut context: Context) -> Result { } } -fn run(instructions: Vec, context: Context) -> Result { - let runtime = create_runtime(instructions, context); +fn run( + instructions: Vec, + context: Context, + env: Option, +) -> Result { + let runtime = create_runtime(instructions, context, env); match run_instructions(runtime, 0, false) { Ok((context, _)) => Ok(context), @@ -92,8 +101,8 @@ fn run(instructions: Vec, context: Context) -> Result, context: Context) -> Runtime { - let mut runtime = Runtime::new(context); +fn create_runtime(instructions: Vec, context: Context, env: Option) -> Runtime { + let mut runtime = Runtime::new(context, env); let mut line = 0; for instruction in &instructions { @@ -141,6 +150,7 @@ fn run_instructions( instructions, instruction, line, + &mut runtime.env, ); match command_result { @@ -185,6 +195,7 @@ fn run_instructions( instructions, error, meta_info.clone(), + &mut runtime.env, ) { return Err(ScriptError::Runtime(error, Some(meta_info.clone()))); }; @@ -249,6 +260,7 @@ fn run_on_error_instruction( instructions: &Vec, error: String, meta_info: InstructionMetaInfo, + env: &mut Env, ) -> Result<(), String> { if commands.exists("on_error") { let mut script_instruction = ScriptInstruction::new(); @@ -263,8 +275,15 @@ fn run_on_error_instruction( instruction_type: InstructionType::Script(script_instruction), }; - let (command_result, output_variable) = - run_instruction(commands, variables, state, instructions, instruction, 0); + let (command_result, output_variable) = run_instruction( + commands, + variables, + state, + instructions, + instruction, + 0, + env, + ); match command_result { CommandResult::Exit(output) => { @@ -288,6 +307,7 @@ pub fn run_instruction( instructions: &Vec, instruction: Instruction, line: usize, + env: &mut Env, ) -> (CommandResult, Option) { let mut output_variable = None; let command_result = match instruction.instruction_type { @@ -314,6 +334,7 @@ pub fn run_instruction( instructions, commands, line, + env, ) } else { command_instance.run(command_arguments) diff --git a/duckscript/src/runner_test.rs b/duckscript/src/runner_test.rs index 650a7567..4334df00 100644 --- a/duckscript/src/runner_test.rs +++ b/duckscript/src/runner_test.rs @@ -23,14 +23,14 @@ fn assert_end_reason_reached_end(end_reason: EndReason) { #[test] fn run_script_parse_error() { - let result = run_script("!bad", Context::new()); + let result = run_script("!bad", Context::new(), None); assert!(result.is_err()); } #[test] fn run_script_valid() { - let result = run_script("!print test", Context::new()); + let result = run_script("!print test", Context::new(), None); assert!(result.is_ok()); } @@ -40,21 +40,25 @@ fn run_script_runtime_error() { let mut context = Context::new(); let cmd_result = context.commands.set(Box::new(CrashCommand {})); assert!(cmd_result.is_ok()); - let result = run_script_file("./src/test/scripts/crash.ds", context); + let result = run_script_file("./src/test/scripts/crash.ds", context, None); assert!(result.is_err()); } #[test] fn run_script_file_valid() { - let result = run_script_file("./src/test/scripts/print_preprocessor.ds", Context::new()); + let result = run_script_file( + "./src/test/scripts/print_preprocessor.ds", + Context::new(), + None, + ); assert!(result.is_ok()); } #[test] fn run_no_instructions() { - let result = run(vec![], Context::new()); + let result = run(vec![], Context::new(), None); assert!(result.is_ok()); } @@ -71,7 +75,7 @@ fn run_empty_instructions() { instruction_type: InstructionType::Empty, }); - let result = run(instructions, Context::new()); + let result = run(instructions, Context::new(), None); assert!(result.is_ok()); } @@ -88,7 +92,7 @@ fn run_pre_processor_instructions() { instruction_type: InstructionType::PreProcess(PreProcessInstruction::new()), }); - let result = run(instructions, Context::new()); + let result = run(instructions, Context::new(), None); assert!(result.is_ok()); } @@ -105,7 +109,7 @@ fn run_no_command_script_instructions() { instruction_type: InstructionType::Script(ScriptInstruction::new()), }); - let result = run(instructions, Context::new()); + let result = run(instructions, Context::new(), None); assert!(result.is_ok()); } @@ -126,7 +130,7 @@ fn run_all_types_instructions() { instruction_type: InstructionType::Script(ScriptInstruction::new()), }); - let result = run(instructions, Context::new()); + let result = run(instructions, Context::new(), None); assert!(result.is_ok()); } @@ -148,7 +152,7 @@ fn create_runtime_with_labels() { instruction_type: InstructionType::Script(script_instruction), }); - let runtime = create_runtime(instructions, Context::new()); + let runtime = create_runtime(instructions, Context::new(), None); assert_eq!(runtime.label_to_line.get("test1"), Some(&0)); assert_eq!(runtime.label_to_line.get("test2"), Some(&1)); @@ -165,7 +169,7 @@ fn run_instructions_unknown_command() { instruction_type: InstructionType::Script(script_instruction), }); - let runtime = create_runtime(instructions, Context::new()); + let runtime = create_runtime(instructions, Context::new(), None); let context_result = run_instructions(runtime, 0, false); @@ -181,7 +185,7 @@ fn run_instructions_start_bigger_then_script() { instruction_type: InstructionType::Script(ScriptInstruction::new()), }); - let runtime = create_runtime(instructions, Context::new()); + let runtime = create_runtime(instructions, Context::new(), None); let context_result = run_instructions(runtime, 10, false); @@ -211,7 +215,7 @@ fn run_instructions_start_after_bad_command() { result = context.commands.set(Box::new(SetCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 1, false); @@ -239,7 +243,7 @@ fn run_instructions_exit_result_no_output() { let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -272,7 +276,7 @@ fn run_instructions_exit_result_with_string_output() { let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -308,7 +312,7 @@ fn run_instructions_exit_result_with_0_output() { let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -341,7 +345,7 @@ fn run_instructions_exit_result_with_error_code_output() { let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -364,7 +368,7 @@ fn run_instructions_error_result() { let result = context.commands.set(Box::new(ErrorCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -405,7 +409,7 @@ fn run_instructions_error_result_with_on_error() { result = context.commands.set(Box::new(OnErrorCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 2, false); @@ -435,7 +439,7 @@ fn run_instructions_crash_result() { let result = context.commands.set(Box::new(CrashCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -457,7 +461,7 @@ fn run_instructions_crash_result_repl_mode() { let result = context.commands.set(Box::new(CrashCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, true); @@ -477,7 +481,7 @@ fn run_instructions_continue_result_no_output() { instruction_type: InstructionType::Empty, }); - let runtime = create_runtime(instructions, Context::new()); + let runtime = create_runtime(instructions, Context::new(), None); let context_result = run_instructions(runtime, 0, false); @@ -512,7 +516,7 @@ fn run_instructions_continue_result_with_output() { let result = context.commands.set(Box::new(SetCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -565,7 +569,7 @@ fn run_instructions_goto_label_result_no_output() { result = context.commands.set(Box::new(GoToLabelCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -615,7 +619,7 @@ fn run_instructions_goto_label_result_with_output() { result = context.commands.set(Box::new(GoToLabelCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -668,7 +672,7 @@ fn run_instructions_goto_line_result_no_output() { result = context.commands.set(Box::new(GoToLineCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -718,7 +722,7 @@ fn run_instructions_goto_line_result_with_output() { result = context.commands.set(Box::new(GoToLineCommand {})); assert!(result.is_ok()); - let runtime = create_runtime(instructions, context); + let runtime = create_runtime(instructions, context, None); let context_result = run_instructions(runtime, 0, false); @@ -784,6 +788,7 @@ fn run_instruction_empty_instruction() { }; let mut context = Context::new(); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -792,6 +797,7 @@ fn run_instruction_empty_instruction() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -806,6 +812,7 @@ fn run_instruction_pre_processor_instruction() { }; let mut context = Context::new(); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -814,6 +821,7 @@ fn run_instruction_pre_processor_instruction() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -828,6 +836,7 @@ fn run_instruction_script_instruction_no_command() { }; let mut context = Context::new(); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -836,6 +845,7 @@ fn run_instruction_script_instruction_no_command() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -853,6 +863,7 @@ fn run_instruction_script_instruction_unknown_command() { }; let mut context = Context::new(); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -861,6 +872,7 @@ fn run_instruction_script_instruction_unknown_command() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -880,6 +892,7 @@ fn run_instruction_script_instruction_continue_result_no_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(SetCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -888,6 +901,7 @@ fn run_instruction_script_instruction_continue_result_no_output() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -909,6 +923,7 @@ fn run_instruction_script_instruction_continue_result_with_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(SetCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -917,6 +932,7 @@ fn run_instruction_script_instruction_continue_result_with_output() { &vec![], instruction, 0, + &mut env, ); assert_eq!(output_variable.unwrap(), "out"); @@ -939,6 +955,7 @@ fn run_instruction_script_instruction_exit_result_no_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -947,6 +964,7 @@ fn run_instruction_script_instruction_exit_result_no_output() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -968,6 +986,7 @@ fn run_instruction_script_instruction_exit_result_with_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(ExitCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -976,6 +995,7 @@ fn run_instruction_script_instruction_exit_result_with_output() { &vec![], instruction, 0, + &mut env, ); assert_eq!(output_variable.unwrap(), "out"); @@ -998,6 +1018,7 @@ fn run_instruction_script_instruction_goto_label_result_no_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(GoToLabelCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1006,6 +1027,7 @@ fn run_instruction_script_instruction_goto_label_result_no_output() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -1027,6 +1049,7 @@ fn run_instruction_script_instruction_goto_label_result_with_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(GoToLabelCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1035,6 +1058,7 @@ fn run_instruction_script_instruction_goto_label_result_with_output() { &vec![], instruction, 0, + &mut env, ); assert_eq!(output_variable.unwrap(), "out"); @@ -1057,6 +1081,7 @@ fn run_instruction_script_instruction_goto_line_result_no_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(GoToLineCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1065,6 +1090,7 @@ fn run_instruction_script_instruction_goto_line_result_no_output() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -1086,6 +1112,7 @@ fn run_instruction_script_instruction_goto_line_result_with_output() { let mut context = Context::new(); let result = context.commands.set(Box::new(GoToLineCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1094,6 +1121,7 @@ fn run_instruction_script_instruction_goto_line_result_with_output() { &vec![], instruction, 0, + &mut env, ); assert_eq!(output_variable.unwrap(), "out"); @@ -1116,6 +1144,7 @@ fn run_instruction_script_instruction_error_result() { let mut context = Context::new(); let result = context.commands.set(Box::new(ErrorCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1124,6 +1153,7 @@ fn run_instruction_script_instruction_error_result() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_none()); @@ -1145,6 +1175,7 @@ fn run_instruction_control_characters() { let mut context = Context::new(); let result = context.commands.set(Box::new(SetCommand {})); assert!(result.is_ok()); + let mut env = Env::default(); let (command_result, output_variable) = run_instruction( &mut context.commands, @@ -1153,6 +1184,7 @@ fn run_instruction_control_characters() { &vec![], instruction, 0, + &mut env, ); assert!(output_variable.is_some()); @@ -1167,6 +1199,7 @@ fn run_on_error_instruction_no_command() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); let result = run_on_error_instruction( &mut commands, @@ -1175,6 +1208,7 @@ fn run_on_error_instruction_no_command() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_ok()); @@ -1185,6 +1219,7 @@ fn run_on_error_instruction_unknown_command() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); commands .aliases @@ -1197,6 +1232,7 @@ fn run_on_error_instruction_unknown_command() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_ok()); @@ -1207,6 +1243,7 @@ fn run_on_error_instruction_exit_response() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); let set_result = commands.set(Box::new(ExitCommand {})); assert!(set_result.is_ok()); @@ -1221,6 +1258,7 @@ fn run_on_error_instruction_exit_response() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_err()); @@ -1231,6 +1269,7 @@ fn run_on_error_instruction_crash_response() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); let set_result = commands.set(Box::new(CrashCommand {})); assert!(set_result.is_ok()); @@ -1245,6 +1284,7 @@ fn run_on_error_instruction_crash_response() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_err()); @@ -1255,6 +1295,7 @@ fn run_on_error_instruction_continue_response() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); let set_result = commands.set(Box::new(SetCommand {})); assert!(set_result.is_ok()); @@ -1269,6 +1310,7 @@ fn run_on_error_instruction_continue_response() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_ok()); @@ -1279,6 +1321,7 @@ fn run_on_error_instruction_error_response() { let mut commands = Commands::new(); let mut variables = HashMap::new(); let mut state = HashMap::new(); + let mut env = Env::default(); let set_result = commands.set(Box::new(ErrorCommand {})); assert!(set_result.is_ok()); @@ -1293,6 +1336,7 @@ fn run_on_error_instruction_error_response() { &vec![], "error".to_string(), InstructionMetaInfo::new(), + &mut env, ); assert!(result.is_ok()); diff --git a/duckscript/src/test/mod.rs b/duckscript/src/test/mod.rs index eeaae3fd..b1c05c41 100644 --- a/duckscript/src/test/mod.rs +++ b/duckscript/src/test/mod.rs @@ -1,4 +1,5 @@ use crate::types::command::{Command, CommandResult, Commands, GoToValue}; +use crate::types::env::Env; use crate::types::instruction::{ Instruction, InstructionType, PreProcessInstruction, ScriptInstruction, }; @@ -76,6 +77,7 @@ impl Command for OnErrorCommand { _instructions: &Vec, _commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { let mut index = 0; for argument in arguments { @@ -83,6 +85,8 @@ impl Command for OnErrorCommand { variables.insert(index.to_string(), argument.clone()); } + writeln!(env.out, "{}", "test").unwrap(); + CommandResult::Continue(None) } } diff --git a/duckscript/src/types/command.rs b/duckscript/src/types/command.rs index 84d6e8b2..3134fe06 100644 --- a/duckscript/src/types/command.rs +++ b/duckscript/src/types/command.rs @@ -7,6 +7,7 @@ #[path = "./command_test.rs"] mod command_test; +use crate::types::env::Env; use crate::types::error::ScriptError; use crate::types::instruction::Instruction; use crate::types::runtime::StateValue; @@ -75,6 +76,7 @@ pub trait Command { /// * `instructions` - The entire list of instructions which make up the currently running script /// * `commands` - The currently known commands /// * `line` - The current instruction line number (global line number after including all scripts into one global script) + /// * `env` - The current runtime env with access to out/err writers, etc... fn run_with_context( &self, _arguments: Vec, @@ -84,6 +86,7 @@ pub trait Command { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { CommandResult::Crash(format!("Not implemented for command: {}", &self.name()).to_string()) } diff --git a/duckscript/src/types/command_test.rs b/duckscript/src/types/command_test.rs index 6d665580..fbd8976e 100644 --- a/duckscript/src/types/command_test.rs +++ b/duckscript/src/types/command_test.rs @@ -82,6 +82,7 @@ fn command_default_run_with_context() { } let mut context = Context::new(); + let mut env = Env::default(); let command = InnerCommand {}; let result = command.run_with_context( vec![], @@ -91,6 +92,7 @@ fn command_default_run_with_context() { &vec![], &mut context.commands, 0, + &mut env, ); test::validate_continue_result(&result, None); diff --git a/duckscript/src/types/env.rs b/duckscript/src/types/env.rs new file mode 100644 index 00000000..340b53e6 --- /dev/null +++ b/duckscript/src/types/env.rs @@ -0,0 +1,42 @@ +//! # env +//! +//! The runtime env structures. +//! + +#[cfg(test)] +#[path = "./env_test.rs"] +mod env_test; + +use std::io::{stderr, stdout, Write}; + +/// The runtime env +pub struct Env { + /// The output writer + pub out: Box, + /// The error writer + pub err: Box, +} + +impl Env { + /// Creates and returns a new instance. + pub fn default() -> Env { + Env { + out: Box::new(stdout()), + err: Box::new(stderr()), + } + } + + /// Creates and returns a new instance. + pub fn new(out: Option>, err: Option>) -> Env { + Env { + out: match out { + Some(value) => value, + None => Box::new(stdout()), + }, + err: match err { + Some(value) => value, + None => Box::new(stderr()), + }, + } + } +} diff --git a/duckscript/src/types/env_test.rs b/duckscript/src/types/env_test.rs new file mode 100644 index 00000000..c66ef5fc --- /dev/null +++ b/duckscript/src/types/env_test.rs @@ -0,0 +1,26 @@ +use super::*; + +fn validate_env(env: &mut Env) { + writeln!(env.out, "test").unwrap(); +} + +#[test] +fn env_default() { + let mut env = Env::default(); + + validate_env(&mut env); +} + +#[test] +fn env_new_none() { + let mut env = Env::new(None, None); + + validate_env(&mut env); +} + +#[test] +fn env_new_with_values() { + let mut env = Env::new(Some(Box::new(stdout())), Some(Box::new(stdout()))); + + validate_env(&mut env); +} diff --git a/duckscript/src/types/mod.rs b/duckscript/src/types/mod.rs index 0553f3a2..0f92cd8f 100755 --- a/duckscript/src/types/mod.rs +++ b/duckscript/src/types/mod.rs @@ -3,6 +3,7 @@ //! All duckscript types. //! pub mod command; +pub mod env; pub mod error; pub mod instruction; pub mod runtime; diff --git a/duckscript/src/types/runtime.rs b/duckscript/src/types/runtime.rs index a70b41fb..fa1d748a 100644 --- a/duckscript/src/types/runtime.rs +++ b/duckscript/src/types/runtime.rs @@ -8,6 +8,7 @@ mod runtime_test; use crate::types::command::Commands; +use crate::types::env::Env; use crate::types::instruction::Instruction; use std::any::Any; use std::cell::RefCell; @@ -75,15 +76,21 @@ pub struct Runtime { pub label_to_line: HashMap, /// The runtime context pub context: Context, + /// The runtime env + pub env: Env, } impl Runtime { /// Creates and returns a new instance. - pub fn new(context: Context) -> Runtime { + pub fn new(context: Context, env: Option) -> Runtime { Runtime { instructions: None, label_to_line: HashMap::new(), context, + env: match env { + Some(value) => value, + None => Env::default(), + }, } } } diff --git a/duckscript/src/types/runtime_test.rs b/duckscript/src/types/runtime_test.rs index ab529c20..091eea86 100644 --- a/duckscript/src/types/runtime_test.rs +++ b/duckscript/src/types/runtime_test.rs @@ -10,11 +10,25 @@ fn context_new() { } #[test] -fn runtime_new() { +fn runtime_new_no_env() { let mut context = Context::new(); context.variables.insert("a".to_string(), "b".to_string()); - let runtime = Runtime::new(context); + let runtime = Runtime::new(context, None); + + assert!(runtime.instructions.is_none()); + assert!(runtime.label_to_line.is_empty()); + assert!(runtime.context.variables.contains_key("a")); +} + +#[test] +fn runtime_new_with_env() { + let mut context = Context::new(); + context.variables.insert("a".to_string(), "b".to_string()); + + let env = Env::default(); + + let runtime = Runtime::new(context, Some(env)); assert!(runtime.instructions.is_none()); assert!(runtime.label_to_line.is_empty()); diff --git a/duckscript_cli/src/main.rs b/duckscript_cli/src/main.rs index 4ddb9023..91f64585 100755 --- a/duckscript_cli/src/main.rs +++ b/duckscript_cli/src/main.rs @@ -100,9 +100,9 @@ fn run_script(value: &str, is_file: bool) -> Result<(), ScriptError> { let context = create_context()?; if is_file { - runner::run_script_file(value, context)?; + runner::run_script_file(value, context, None)?; } else { - runner::run_script(value, context)?; + runner::run_script(value, context, None)?; } Ok(()) diff --git a/duckscript_sdk/src/lib_test.rs b/duckscript_sdk/src/lib_test.rs index 14311bf1..73c51141 100644 --- a/duckscript_sdk/src/lib_test.rs +++ b/duckscript_sdk/src/lib_test.rs @@ -36,6 +36,7 @@ fn test_scripts() { unset_env DUCKSCRIPT_TEST_RUST "#, context, + None, ); assert!(result.is_ok()); diff --git a/duckscript_sdk/src/sdk/internal/sdkdocs/mod.rs b/duckscript_sdk/src/sdk/internal/sdkdocs/mod.rs index 62e12025..c968774b 100755 --- a/duckscript_sdk/src/sdk/internal/sdkdocs/mod.rs +++ b/duckscript_sdk/src/sdk/internal/sdkdocs/mod.rs @@ -2,6 +2,7 @@ use crate::utils::io; use crate::utils::pckg; use duckscript::types::command::Commands; use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -41,6 +42,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Documentation output directory not provided.".to_string()) @@ -85,7 +87,9 @@ impl Command for CommandImpl { } }; } else { - println!("Command: {} skipped.", &name); + if let Err(error) = writeln!(env.out, "Command: {} skipped.", &name) { + return CommandResult::Error(error.to_string()); + } } } diff --git a/duckscript_sdk/src/sdk/std/collections/array/mod.rs b/duckscript_sdk/src/sdk/std/collections/array/mod.rs index e027a9d9..ce188012 100755 --- a/duckscript_sdk/src/sdk/std/collections/array/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let mut array = vec![]; diff --git a/duckscript_sdk/src/sdk/std/collections/array_clear/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_clear/mod.rs index 4db7be1c..e3f5a03e 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_clear/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_clear/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_get/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_get/mod.rs index 5f4cf689..a2522e5b 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_get/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_get/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, get_optional_as_string, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Array handle or item index not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_length/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_length/mod.rs index 91336936..96ad0ba9 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_length/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_length/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -48,6 +49,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_pop/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_pop/mod.rs index 48a5e910..e47f3d13 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_pop/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_pop/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, get_optional_as_string, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_push/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_push/mod.rs index 1ef1aedb..1c6eb1b5 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_push/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_push/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -48,6 +49,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_remove/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_remove/mod.rs index 933a6994..737e9bce 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_remove/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_remove/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Invalid input provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs b/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs index ae110240..b81a8095 100755 --- a/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/array_set/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_list}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 3 { CommandResult::Error("Invalid input provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/is_array/mod.rs b/duckscript_sdk/src/sdk/std/collections/is_array/mod.rs index 96ec6af0..d6568b23 100755 --- a/duckscript_sdk/src/sdk/std/collections/is_array/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/is_array/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/is_map/mod.rs b/duckscript_sdk/src/sdk/std/collections/is_map/mod.rs index 020db202..3994b0b1 100755 --- a/duckscript_sdk/src/sdk/std/collections/is_map/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/is_map/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/is_set/mod.rs b/duckscript_sdk/src/sdk/std/collections/is_set/mod.rs index a9e63547..4d85b3f3 100755 --- a/duckscript_sdk/src/sdk/std/collections/is_set/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/is_set/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map/mod.rs b/duckscript_sdk/src/sdk/std/collections/map/mod.rs index 2ac531df..5b7ce46c 100755 --- a/duckscript_sdk/src/sdk/std/collections/map/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let map = HashMap::new(); diff --git a/duckscript_sdk/src/sdk/std/collections/map_clear/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_clear/mod.rs index 206e9f6a..56d1c8c6 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_clear/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_clear/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_map}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_get/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_get/mod.rs index ae07a916..dcbaee89 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_get/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_get/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, get_optional_as_string, mutate_map}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_keys/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_keys/mod.rs index 3894e3a9..9b8b73be 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_keys/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_keys/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, put_handle}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_load_properties/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_load_properties/mod.rs index ac2b1e8f..f841801d 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_load_properties/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_load_properties/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_map}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use java_properties::read; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Map handle and/or properties text not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_put/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_put/mod.rs index 538cb2c2..1c224957 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_put/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_put/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_map}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_remove/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_remove/mod.rs index 89ef905b..c4f31b22 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_remove/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_remove/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, get_optional_as_string, mutate_map}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_size/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_size/mod.rs index 87c56231..dcce577d 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_size/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_size/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/map_to_properties/mod.rs b/duckscript_sdk/src/sdk/std/collections/map_to_properties/mod.rs index e915ffe4..ff99dafc 100755 --- a/duckscript_sdk/src/sdk/std/collections/map_to_properties/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/map_to_properties/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_as_string, get_handles_sub_state}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use java_properties::write; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Map handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/range/mod.rs b/duckscript_sdk/src/sdk/std/collections/range/mod.rs index a4e77c56..8fd845f0 100755 --- a/duckscript_sdk/src/sdk/std/collections/range/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/range/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Invalid arguments provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/read_properties/mod.rs b/duckscript_sdk/src/sdk/std/collections/read_properties/mod.rs index 0c679d0d..0606c316 100755 --- a/duckscript_sdk/src/sdk/std/collections/read_properties/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/read_properties/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use java_properties::read; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 1 { CommandResult::Error("Missing properties text argument.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set/mod.rs b/duckscript_sdk/src/sdk/std/collections/set/mod.rs index 757c9f74..aa747315 100755 --- a/duckscript_sdk/src/sdk/std/collections/set/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::{HashMap, HashSet}; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let mut set = HashSet::new(); diff --git a/duckscript_sdk/src/sdk/std/collections/set_clear/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_clear/mod.rs index 4d6130f1..786834ea 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_clear/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_clear/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_set}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set_contains/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_contains/mod.rs index afb8c80c..344eb92b 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_contains/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_contains/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_set}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set_put/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_put/mod.rs index 659f698c..6335ea28 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_put/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_put/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_set}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set_remove/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_remove/mod.rs index 497c7cd6..e608b31c 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_remove/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_remove/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, mutate_set}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set_size/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_size/mod.rs index b2b5a844..b110f816 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_size/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_size/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/set_to_array/mod.rs b/duckscript_sdk/src/sdk/std/collections/set_to_array/mod.rs index 66eefae3..3e489c7b 100755 --- a/duckscript_sdk/src/sdk/std/collections/set_to_array/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/set_to_array/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_handles_sub_state, put_handle}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Set handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/collections/write_properties/mod.rs b/duckscript_sdk/src/sdk/std/collections/write_properties/mod.rs index f0d9f110..a5b951fd 100755 --- a/duckscript_sdk/src/sdk/std/collections/write_properties/mod.rs +++ b/duckscript_sdk/src/sdk/std/collections/write_properties/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use java_properties::write; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 1 { CommandResult::Error("Missing properties names.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs index c3ae03cd..7723effb 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,12 +44,16 @@ impl Command for CommandImpl { instructions: &Vec, _commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { let string_value = format!("{:#?}", instructions).to_string(); if output_variable.is_none() { - println!("{}", string_value); - } + match writeln!(env.out, "{}", string_value) { + Ok(_) => (), + Err(error) => return CommandResult::Error(error.to_string()), + } + }; CommandResult::Continue(Some(string_value)) } diff --git a/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs index 57cc534f..c86ce94b 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,11 +44,15 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { let string_value = format!("{:#?}", state).to_string(); if output_variable.is_none() { - println!("{}", string_value); + match writeln!(env.out, "{}", &string_value) { + Ok(_) => (), + Err(error) => return CommandResult::Error(error.to_string()), + }; } CommandResult::Continue(Some(string_value)) diff --git a/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs index 9f64e712..a3549e7b 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,11 +44,15 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { let string_value = format!("{:#?}", variables).to_string(); if output_variable.is_none() { - println!("{}", string_value); + match writeln!(env.out, "{}", string_value) { + Ok(_) => (), + Err(error) => return CommandResult::Error(error.to_string()), + }; } CommandResult::Continue(Some(string_value)) diff --git a/duckscript_sdk/src/sdk/std/echo/mod.rs b/duckscript_sdk/src/sdk/std/echo/mod.rs index 9fb3f86d..80831dfc 100755 --- a/duckscript_sdk/src/sdk/std/echo/mod.rs +++ b/duckscript_sdk/src/sdk/std/echo/mod.rs @@ -1,5 +1,9 @@ use crate::utils::pckg; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; #[cfg(test)] #[path = "./mod_test.rs"] @@ -27,14 +31,31 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, arguments: Vec) -> CommandResult { + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { for argument in &arguments { - print!("{} ", argument); + if let Err(error) = write!(env.out, "{}", argument) { + return CommandResult::Error(error.to_string()); + } } - println!(); - - CommandResult::Continue(Some(arguments.len().to_string())) + match writeln!(env.out, "") { + Ok(_) => CommandResult::Continue(Some(arguments.len().to_string())), + Err(error) => CommandResult::Error(error.to_string()), + } } } diff --git a/duckscript_sdk/src/sdk/std/env/env_to_map/mod.rs b/duckscript_sdk/src/sdk/std/env/env_to_map/mod.rs index 73078eba..8deaa867 100755 --- a/duckscript_sdk/src/sdk/std/env/env_to_map/mod.rs +++ b/duckscript_sdk/src/sdk/std/env/env_to_map/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let all_vars = env::vars(); let mut map = HashMap::new(); diff --git a/duckscript_sdk/src/sdk/std/env/print_current_directory/mod.rs b/duckscript_sdk/src/sdk/std/env/print_current_directory/mod.rs index f6923007..1091376e 100755 --- a/duckscript_sdk/src/sdk/std/env/print_current_directory/mod.rs +++ b/duckscript_sdk/src/sdk/std/env/print_current_directory/mod.rs @@ -1,5 +1,9 @@ use crate::utils::pckg; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; use std::env; #[cfg(test)] @@ -28,12 +32,28 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, _arguments: Vec) -> CommandResult { + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + _arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { match env::current_dir() { Ok(directory_path) => { let directory = directory_path.display(); - println!("{}", &directory); - CommandResult::Continue(Some(directory.to_string())) + match writeln!(env.out, "{}", &directory) { + Ok(_) => CommandResult::Continue(Some(directory.to_string())), + Err(error) => CommandResult::Error(error.to_string()), + } } Err(_) => CommandResult::Continue(None), } diff --git a/duckscript_sdk/src/sdk/std/env/set_env/mod.rs b/duckscript_sdk/src/sdk/std/env/set_env/mod.rs index fa5b9f4b..27929e5c 100755 --- a/duckscript_sdk/src/sdk/std/env/set_env/mod.rs +++ b/duckscript_sdk/src/sdk/std/env/set_env/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{get_as_string, get_handles_sub_state}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing environment variable name and value.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/eval/mod.rs b/duckscript_sdk/src/sdk/std/eval/mod.rs index 80d056d5..41acab45 100755 --- a/duckscript_sdk/src/sdk/std/eval/mod.rs +++ b/duckscript_sdk/src/sdk/std/eval/mod.rs @@ -1,5 +1,6 @@ use crate::utils::{eval, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,8 +44,9 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { - eval::eval_with_error(&arguments, state, variables, commands) + eval::eval_with_error(&arguments, state, variables, commands, env) } } diff --git a/duckscript_sdk/src/sdk/std/flowcontrol/end/mod.rs b/duckscript_sdk/src/sdk/std/flowcontrol/end/mod.rs index ee0bcc37..e679e976 100755 --- a/duckscript_sdk/src/sdk/std/flowcontrol/end/mod.rs +++ b/duckscript_sdk/src/sdk/std/flowcontrol/end/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::flowcontrol::get_line_key; use crate::utils::state::get_core_sub_state_for_command; use duckscript::runner; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::{ Instruction, InstructionMetaInfo, InstructionType, ScriptInstruction, }; @@ -69,6 +70,7 @@ impl Command for CommandImpl { instructions: &Vec, commands: &mut Commands, line: usize, + env: &mut Env, ) -> CommandResult { match get_command(line, state) { Some(command) => { @@ -88,6 +90,7 @@ impl Command for CommandImpl { instructions, instruction, line, + env, ); command_result diff --git a/duckscript_sdk/src/sdk/std/flowcontrol/forin/mod.rs b/duckscript_sdk/src/sdk/std/flowcontrol/forin/mod.rs index f4937e5d..17688f5a 100755 --- a/duckscript_sdk/src/sdk/std/flowcontrol/forin/mod.rs +++ b/duckscript_sdk/src/sdk/std/flowcontrol/forin/mod.rs @@ -5,6 +5,7 @@ use crate::utils::state::{ }; use crate::utils::{instruction_query, pckg}; use duckscript::types::command::{Command, CommandResult, Commands, GoToValue}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; @@ -322,6 +323,7 @@ impl Command for ForInCommand { instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() != 3 || arguments[1] != "in" { CommandResult::Error("Invalid for/in statement".to_string()) @@ -424,6 +426,7 @@ impl Command for EndForInCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { match pop_call_info_for_line(line, state, true) { Some(call_info) => { diff --git a/duckscript_sdk/src/sdk/std/flowcontrol/function/mod.rs b/duckscript_sdk/src/sdk/std/flowcontrol/function/mod.rs index 6feac336..b8693721 100755 --- a/duckscript_sdk/src/sdk/std/flowcontrol/function/mod.rs +++ b/duckscript_sdk/src/sdk/std/flowcontrol/function/mod.rs @@ -3,6 +3,7 @@ use crate::types::scope::get_line_context_name; use crate::utils::state::{get_core_sub_state_for_command, get_list, get_sub_state}; use crate::utils::{annotation, instruction_query, pckg, scope}; use duckscript::types::command::{Command, CommandResult, Commands, GoToValue}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; @@ -299,6 +300,7 @@ impl Command for FunctionCommand { instructions: &Vec, commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing function name.".to_string()) @@ -417,6 +419,7 @@ impl Command for FunctionCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { run_call( @@ -499,6 +502,7 @@ impl Command for EndFunctionCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { let line_context_name = get_line_context_name(state); @@ -560,6 +564,7 @@ impl Command for ReturnCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { let line_context_name = get_line_context_name(state); diff --git a/duckscript_sdk/src/sdk/std/flowcontrol/ifelse/mod.rs b/duckscript_sdk/src/sdk/std/flowcontrol/ifelse/mod.rs index 6c27160c..d85d03e3 100755 --- a/duckscript_sdk/src/sdk/std/flowcontrol/ifelse/mod.rs +++ b/duckscript_sdk/src/sdk/std/flowcontrol/ifelse/mod.rs @@ -3,6 +3,7 @@ use crate::types::scope::get_line_context_name; use crate::utils::state::{get_core_sub_state_for_command, get_list, get_sub_state}; use crate::utils::{condition, instruction_query, pckg}; use duckscript::types::command::{Command, CommandResult, Commands, GoToValue}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; @@ -356,6 +357,7 @@ impl Command for IfCommand { instructions: &Vec, commands: &mut Commands, line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing condition".to_string()) @@ -373,6 +375,7 @@ impl Command for IfCommand { state, variables, commands, + env, ) { Ok(passed) => { if passed { @@ -460,6 +463,7 @@ impl Command for ElseIfCommand { instructions: &Vec, commands: &mut Commands, line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing condition".to_string()) @@ -472,7 +476,7 @@ impl Command for ElseIfCommand { } else { let if_else_info = call_info.meta_info.clone(); let line_context_name = get_line_context_name(state); - match condition::eval_condition(arguments, instructions, state, variables, commands) { + match condition::eval_condition(arguments, instructions, state, variables, commands, env) { Ok(passed) => { if passed { let next_line = if call_info.else_line_index + 1 < if_else_info.else_lines.len() { @@ -558,6 +562,7 @@ impl Command for ElseCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { match pop_call_info_for_line(line, state) { Some(call_info) => { diff --git a/duckscript_sdk/src/sdk/std/flowcontrol/while_mod/mod.rs b/duckscript_sdk/src/sdk/std/flowcontrol/while_mod/mod.rs index ccbc7bc2..6aea076e 100755 --- a/duckscript_sdk/src/sdk/std/flowcontrol/while_mod/mod.rs +++ b/duckscript_sdk/src/sdk/std/flowcontrol/while_mod/mod.rs @@ -3,6 +3,7 @@ use crate::types::scope::get_line_context_name; use crate::utils::state::{get_core_sub_state_for_command, get_list, get_sub_state}; use crate::utils::{condition, instruction_query, pckg}; use duckscript::types::command::{Command, CommandResult, Commands, GoToValue}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; @@ -279,6 +280,7 @@ impl Command for WhileCommand { instructions: &Vec, commands: &mut Commands, line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing condition".to_string()) @@ -296,6 +298,7 @@ impl Command for WhileCommand { state, variables, commands, + env, ) { Ok(passed) => { if passed { @@ -367,6 +370,7 @@ impl Command for EndWhileCommand { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { match pop_call_info_for_line(line, state) { Some(call_info) => { diff --git a/duckscript_sdk/src/sdk/std/fs/gitignore_path_array/mod.rs b/duckscript_sdk/src/sdk/std/fs/gitignore_path_array/mod.rs index cdcdf812..bd6c889d 100755 --- a/duckscript_sdk/src/sdk/std/fs/gitignore_path_array/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/gitignore_path_array/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use fsio::path::from_path::FromPath; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Root directory not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/fs/glob_array/mod.rs b/duckscript_sdk/src/sdk/std/fs/glob_array/mod.rs index 8ccc645c..a662912e 100755 --- a/duckscript_sdk/src/sdk/std/fs/glob_array/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/glob_array/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use fsio::path::from_path::FromPath; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Glob pattern not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/fs/list/mod.rs b/duckscript_sdk/src/sdk/std/fs/list/mod.rs index 0f197af6..6d0fc89f 100755 --- a/duckscript_sdk/src/sdk/std/fs/list/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/list/mod.rs @@ -1,5 +1,8 @@ use crate::utils::{flags, pckg}; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; use fs_extra::dir::{ls, DirEntryAttr, DirEntryValue}; use fsio::path::{get_basename, get_parent_directory}; use std::collections::{HashMap, HashSet}; @@ -42,7 +45,7 @@ fn get_boolean_value(key: DirEntryAttr, attributes: &HashMap, extended_details: bool) { +fn print_entry(env: &mut Env, item: &HashMap, extended_details: bool) { if extended_details { let directory_flag = if get_boolean_value(DirEntryAttr::IsDir, &item) { "" @@ -50,14 +53,21 @@ fn print_entry(item: &HashMap, extended_details: bo "" }; - println!( + writeln!( + env.out, "{}\t{}\t{}", get_u64_value(DirEntryAttr::FileSize, &item), directory_flag, get_string_value(DirEntryAttr::FullName, &item) - ); + ) + .unwrap(); } else { - println!("{} ", get_string_value(DirEntryAttr::FullName, &item)); + writeln!( + env.out, + "{} ", + get_string_value(DirEntryAttr::FullName, &item) + ) + .unwrap(); } } @@ -83,7 +93,21 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, arguments: Vec) -> CommandResult { + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { let (path_str, flags) = if arguments.is_empty() { (".", "") } else if arguments.len() == 1 { @@ -138,13 +162,13 @@ impl Command for CommandImpl { let item_name = get_string_value(DirEntryAttr::FullName, &item); if item_name == file_name { - print_entry(&item, extended_details); + print_entry(env, &item, extended_details); break; } } } else { for item in items { - print_entry(&item, extended_details); + print_entry(env, &item, extended_details); } } diff --git a/duckscript_sdk/src/sdk/std/fs/print/mod.rs b/duckscript_sdk/src/sdk/std/fs/print/mod.rs index 2a1607e2..7c7c054d 100755 --- a/duckscript_sdk/src/sdk/std/fs/print/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/print/mod.rs @@ -1,5 +1,9 @@ use crate::utils::{io, pckg}; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; #[cfg(test)] #[path = "./mod_test.rs"] @@ -27,7 +31,21 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, arguments: Vec) -> CommandResult { + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("File name not provided.".to_string()) } else { @@ -41,8 +59,10 @@ impl Command for CommandImpl { } } - println!("{}", &all_text); - CommandResult::Continue(Some(all_text)) + match writeln!(env.out, "{}", &all_text) { + Ok(_) => CommandResult::Continue(Some(all_text)), + Err(error) => CommandResult::Error(error.to_string()), + } } } } diff --git a/duckscript_sdk/src/sdk/std/fs/read_bytes/mod.rs b/duckscript_sdk/src/sdk/std/fs/read_bytes/mod.rs index d13f0f95..6a557706 100755 --- a/duckscript_sdk/src/sdk/std/fs/read_bytes/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/read_bytes/mod.rs @@ -1,6 +1,7 @@ use crate::utils::state::put_handle; use crate::utils::{io, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("File name not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/fs/write_bytes/mod.rs b/duckscript_sdk/src/sdk/std/fs/write_bytes/mod.rs index 74959dc8..49ffc5d1 100755 --- a/duckscript_sdk/src/sdk/std/fs/write_bytes/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/write_bytes/mod.rs @@ -1,6 +1,7 @@ use crate::utils::state::get_handles_sub_state; use crate::utils::{io, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("File name and text not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/fs/zip/zip/mod.rs b/duckscript_sdk/src/sdk/std/fs/zip/zip/mod.rs index bb5e2bcd..7fe59946 100644 --- a/duckscript_sdk/src/sdk/std/fs/zip/zip/mod.rs +++ b/duckscript_sdk/src/sdk/std/fs/zip/zip/mod.rs @@ -1,5 +1,6 @@ use crate::utils::{pckg, state}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -51,6 +52,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { return CommandResult::Error( diff --git a/duckscript_sdk/src/sdk/std/is_command_defined/mod.rs b/duckscript_sdk/src/sdk/std/is_command_defined/mod.rs index de2853ba..15a325d4 100755 --- a/duckscript_sdk/src/sdk/std/is_command_defined/mod.rs +++ b/duckscript_sdk/src/sdk/std/is_command_defined/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Command name not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/json/encode/mod.rs b/duckscript_sdk/src/sdk/std/json/encode/mod.rs index aa39f218..29ba7f52 100755 --- a/duckscript_sdk/src/sdk/std/json/encode/mod.rs +++ b/duckscript_sdk/src/sdk/std/json/encode/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::json::OBJECT_VALUE; use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use serde_json::map::Map; @@ -212,6 +213,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("No JSON root variable name provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/json/parse/mod.rs b/duckscript_sdk/src/sdk/std/json/parse/mod.rs index d2424a28..15792085 100755 --- a/duckscript_sdk/src/sdk/std/json/parse/mod.rs +++ b/duckscript_sdk/src/sdk/std/json/parse/mod.rs @@ -2,6 +2,7 @@ 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::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use serde_json::{Result, Value}; @@ -117,6 +118,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("No JSON string provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/lib/alias/set/mod.rs b/duckscript_sdk/src/sdk/std/lib/alias/set/mod.rs index b93a0488..95c9c4ea 100755 --- a/duckscript_sdk/src/sdk/std/lib/alias/set/mod.rs +++ b/duckscript_sdk/src/sdk/std/lib/alias/set/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::lib::alias::ALIAS_STATE_KEY; use crate::utils::state::get_sub_state; use crate::utils::{eval, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -48,12 +49,13 @@ fn create_alias_command( _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { let mut all_arguments = vec![]; all_arguments.append(&mut self.arguments.clone()); all_arguments.append(&mut arguments.clone()); - eval::eval_with_error(&all_arguments, state, variables, commands) + eval::eval_with_error(&all_arguments, state, variables, commands, env) } } @@ -106,6 +108,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Invalid alias provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/lib/alias/unset/mod.rs b/duckscript_sdk/src/sdk/std/lib/alias/unset/mod.rs index decc1ffc..6f4b88e3 100755 --- a/duckscript_sdk/src/sdk/std/lib/alias/unset/mod.rs +++ b/duckscript_sdk/src/sdk/std/lib/alias/unset/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::lib::alias::ALIAS_STATE_KEY; use crate::utils::pckg; use crate::utils::state::get_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() != 1 { CommandResult::Error("Invalid alias name provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/lib/command/remove/mod.rs b/duckscript_sdk/src/sdk/std/lib/command/remove/mod.rs index 41d21018..5fcc3743 100755 --- a/duckscript_sdk/src/sdk/std/lib/command/remove/mod.rs +++ b/duckscript_sdk/src/sdk/std/lib/command/remove/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() != 1 { CommandResult::Error("Invalid command name provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/man/mod.rs b/duckscript_sdk/src/sdk/std/man/mod.rs index de9ac848..18a05f0e 100755 --- a/duckscript_sdk/src/sdk/std/man/mod.rs +++ b/duckscript_sdk/src/sdk/std/man/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -8,12 +9,12 @@ use std::collections::HashMap; #[path = "./mod_test.rs"] mod mod_test; -fn print_help(help_doc: String, name: &str) -> CommandResult { +fn print_help(env: &mut Env, help_doc: String, name: &str) -> CommandResult { if help_doc.is_empty() { - println!("No documentation found for command: {}", name); + writeln!(env.out, "No documentation found for command: {}", name).unwrap(); CommandResult::Continue(None) } else { - println!("{}", &help_doc); + writeln!(env.out, "{}", &help_doc).unwrap(); CommandResult::Continue(Some(help_doc)) } } @@ -53,22 +54,23 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { - print_help(self.help(), &self.name()) + print_help(env, self.help(), &self.name()) } else { let name = &arguments[0]; match commands.get(name) { Some(command) => { let help_doc = command.help(); - print_help(help_doc, name) + print_help(env, help_doc, name) } None => { if name == &self.name() || self.aliases().contains(name) { - print_help(self.help(), &self.name()) + print_help(env, self.help(), &self.name()) } else { - println!("Command: {} not found.", name); + writeln!(env.out, "Command: {} not found.", name).unwrap(); CommandResult::Continue(None) } } diff --git a/duckscript_sdk/src/sdk/std/net/ftp/get_in_memory/mod.rs b/duckscript_sdk/src/sdk/std/net/ftp/get_in_memory/mod.rs index 67001e60..79928421 100755 --- a/duckscript_sdk/src/sdk/std/net/ftp/get_in_memory/mod.rs +++ b/duckscript_sdk/src/sdk/std/net/ftp/get_in_memory/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::net::ftp::{validate_and_run_with_connection, Options}; use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { validate_and_run_with_connection( &arguments, diff --git a/duckscript_sdk/src/sdk/std/net/ftp/list/mod.rs b/duckscript_sdk/src/sdk/std/net/ftp/list/mod.rs index 835e923f..66bb7ade 100755 --- a/duckscript_sdk/src/sdk/std/net/ftp/list/mod.rs +++ b/duckscript_sdk/src/sdk/std/net/ftp/list/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::net::ftp::{run_with_connection, Options}; use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { run_with_connection(&arguments, &mut |_options: &Options, ftp_stream: &mut FtpStream| diff --git a/duckscript_sdk/src/sdk/std/net/ftp/nlst/mod.rs b/duckscript_sdk/src/sdk/std/net/ftp/nlst/mod.rs index 96cefbfe..a81d212d 100755 --- a/duckscript_sdk/src/sdk/std/net/ftp/nlst/mod.rs +++ b/duckscript_sdk/src/sdk/std/net/ftp/nlst/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::net::ftp::{run_with_connection, Options}; use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -46,6 +47,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { run_with_connection(&arguments, &mut |_options: &Options, ftp_stream: &mut FtpStream| diff --git a/duckscript_sdk/src/sdk/std/not/mod.rs b/duckscript_sdk/src/sdk/std/not/mod.rs index 518df0f8..49b5678b 100755 --- a/duckscript_sdk/src/sdk/std/not/mod.rs +++ b/duckscript_sdk/src/sdk/std/not/mod.rs @@ -1,5 +1,6 @@ use crate::utils::{condition, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,11 +44,19 @@ impl Command for CommandImpl { instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing condition".to_string()) } else { - match condition::eval_condition(arguments, instructions, state, variables, commands) { + match condition::eval_condition( + arguments, + instructions, + state, + variables, + commands, + env, + ) { Ok(passed) => { let output = !passed; CommandResult::Continue(Some(output.to_string())) diff --git a/duckscript_sdk/src/sdk/std/on_error/exit_on_error/mod.rs b/duckscript_sdk/src/sdk/std/on_error/exit_on_error/mod.rs index ebeff19f..feeba8cb 100755 --- a/duckscript_sdk/src/sdk/std/on_error/exit_on_error/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/exit_on_error/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::on_error::{get_value, EXIT_ON_ERROR_KEY, STATE_KEY}; use crate::utils::state::get_core_sub_state_for_command; use crate::utils::{condition, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let exit_on_error = if arguments.is_empty() { let value_string = get_value(state, EXIT_ON_ERROR_KEY.to_string()); diff --git a/duckscript_sdk/src/sdk/std/on_error/get_last_error/mod.rs b/duckscript_sdk/src/sdk/std/on_error/get_last_error/mod.rs index ca4b98ff..2ce353e3 100755 --- a/duckscript_sdk/src/sdk/std/on_error/get_last_error/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/get_last_error/mod.rs @@ -1,6 +1,7 @@ use crate::sdk::std::on_error::get_value; use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let value = get_value(state, "error".to_string()); CommandResult::Continue(value) diff --git a/duckscript_sdk/src/sdk/std/on_error/get_last_error_line/mod.rs b/duckscript_sdk/src/sdk/std/on_error/get_last_error_line/mod.rs index ef9b0fcd..60fa311b 100755 --- a/duckscript_sdk/src/sdk/std/on_error/get_last_error_line/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/get_last_error_line/mod.rs @@ -1,6 +1,7 @@ use crate::sdk::std::on_error::get_value; use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let value = get_value(state, "line".to_string()); CommandResult::Continue(value) diff --git a/duckscript_sdk/src/sdk/std/on_error/get_last_error_source/mod.rs b/duckscript_sdk/src/sdk/std/on_error/get_last_error_source/mod.rs index 86610192..62eceed6 100755 --- a/duckscript_sdk/src/sdk/std/on_error/get_last_error_source/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/get_last_error_source/mod.rs @@ -1,6 +1,7 @@ use crate::sdk::std::on_error::get_value; use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let value = get_value(state, "source".to_string()); CommandResult::Continue(value) diff --git a/duckscript_sdk/src/sdk/std/on_error/on_error/mod.rs b/duckscript_sdk/src/sdk/std/on_error/on_error/mod.rs index 860ae05d..1d2bb16b 100755 --- a/duckscript_sdk/src/sdk/std/on_error/on_error/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/on_error/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::on_error::{get_value, EXIT_ON_ERROR_KEY, STATE_KEY}; use crate::utils::state::get_core_sub_state_for_command; use crate::utils::{condition, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if !arguments.is_empty() { let error = arguments[0].clone(); diff --git a/duckscript_sdk/src/sdk/std/on_error/set_error/mod.rs b/duckscript_sdk/src/sdk/std/on_error/set_error/mod.rs index bebec0cb..e33d06e6 100755 --- a/duckscript_sdk/src/sdk/std/on_error/set_error/mod.rs +++ b/duckscript_sdk/src/sdk/std/on_error/set_error/mod.rs @@ -2,6 +2,7 @@ use crate::sdk::std::on_error::STATE_KEY; use crate::utils::pckg; use crate::utils::state::get_core_sub_state_for_command; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, line: usize, + _env: &mut Env, ) -> CommandResult { if !arguments.is_empty() { let error = arguments[0].clone(); diff --git a/duckscript_sdk/src/sdk/std/print/mod.rs b/duckscript_sdk/src/sdk/std/print/mod.rs index 2d691751..839e5b2b 100755 --- a/duckscript_sdk/src/sdk/std/print/mod.rs +++ b/duckscript_sdk/src/sdk/std/print/mod.rs @@ -1,6 +1,10 @@ use crate::utils::pckg; use colored::{Color, ColoredString, Colorize}; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; #[cfg(test)] #[path = "./mod_test.rs"] @@ -134,7 +138,7 @@ fn add_color( } } -pub(crate) fn run_print(arguments: Vec) -> CommandResult { +pub(crate) fn run_print(env: &mut Env, arguments: Vec) -> CommandResult { // collect options let mut styles = vec![]; let mut text_color = None; @@ -187,9 +191,10 @@ pub(crate) fn run_print(arguments: Vec) -> CommandResult { styled_string = add_color(styled_string, background_color, true); styled_string = add_styles(styled_string, styles); - print!("{}", styled_string); - - CommandResult::Continue(Some(count.to_string())) + match write!(env.out, "{}", styled_string) { + Ok(_) => CommandResult::Continue(Some(count.to_string())), + Err(error) => CommandResult::Error(error.to_string()), + } } #[derive(Clone)] @@ -214,8 +219,22 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, arguments: Vec) -> CommandResult { - run_print(arguments) + fn requires_context(&self) -> bool { + true + } + + fn run_with_context( + &self, + arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { + run_print(env, arguments) } } diff --git a/duckscript_sdk/src/sdk/std/println/mod.rs b/duckscript_sdk/src/sdk/std/println/mod.rs index 3800e766..e914d11e 100755 --- a/duckscript_sdk/src/sdk/std/println/mod.rs +++ b/duckscript_sdk/src/sdk/std/println/mod.rs @@ -1,6 +1,10 @@ use crate::sdk::std::print::run_print; use crate::utils::pckg; -use duckscript::types::command::{Command, CommandResult}; +use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; +use duckscript::types::instruction::Instruction; +use duckscript::types::runtime::StateValue; +use std::collections::HashMap; #[cfg(test)] #[path = "./mod_test.rs"] @@ -28,15 +32,31 @@ impl Command for CommandImpl { Box::new((*self).clone()) } - fn run(&self, arguments: Vec) -> CommandResult { - let result = run_print(arguments); + fn requires_context(&self) -> bool { + true + } - match result { - CommandResult::Continue(_) => println!(""), - _ => (), - }; + fn run_with_context( + &self, + arguments: Vec, + _state: &mut HashMap, + _variables: &mut HashMap, + _output_variable: Option, + _instructions: &Vec, + _commands: &mut Commands, + _line: usize, + env: &mut Env, + ) -> CommandResult { + let result = run_print(env, arguments); - return result; + if let CommandResult::Continue(ref _value) = result { + match writeln!(env.out, "") { + Ok(_) => result, + Err(error) => CommandResult::Error(error.to_string()), + } + } else { + result + } } } diff --git a/duckscript_sdk/src/sdk/std/process/exec/mod.rs b/duckscript_sdk/src/sdk/std/process/exec/mod.rs index aa60c413..1025eaf7 100755 --- a/duckscript_sdk/src/sdk/std/process/exec/mod.rs +++ b/duckscript_sdk/src/sdk/std/process/exec/mod.rs @@ -1,6 +1,7 @@ use crate::utils::exec::ExecInput; use crate::utils::{exec, pckg}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -49,6 +50,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let mut input = if output_variable.is_some() { ExecInput::External diff --git a/duckscript_sdk/src/sdk/std/release/mod.rs b/duckscript_sdk/src/sdk/std/release/mod.rs index 43b44e4e..ddc41e0c 100755 --- a/duckscript_sdk/src/sdk/std/release/mod.rs +++ b/duckscript_sdk/src/sdk/std/release/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::{remove_handle, remove_handle_recursive}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Continue(Some("false".to_string())) diff --git a/duckscript_sdk/src/sdk/std/scope/clear/mod.rs b/duckscript_sdk/src/sdk/std/scope/clear/mod.rs index 0134891e..c2a5e729 100755 --- a/duckscript_sdk/src/sdk/std/scope/clear/mod.rs +++ b/duckscript_sdk/src/sdk/std/scope/clear/mod.rs @@ -1,6 +1,7 @@ use crate::types::scope::clear; use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Scope name not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/scope/pop_stack/mod.rs b/duckscript_sdk/src/sdk/std/scope/pop_stack/mod.rs index 794976e3..f24bc87a 100755 --- a/duckscript_sdk/src/sdk/std/scope/pop_stack/mod.rs +++ b/duckscript_sdk/src/sdk/std/scope/pop_stack/mod.rs @@ -1,5 +1,6 @@ use crate::utils::{pckg, scope}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let copy = if arguments.is_empty() { &[] diff --git a/duckscript_sdk/src/sdk/std/scope/push_stack/mod.rs b/duckscript_sdk/src/sdk/std/scope/push_stack/mod.rs index eafd652d..5e632956 100755 --- a/duckscript_sdk/src/sdk/std/scope/push_stack/mod.rs +++ b/duckscript_sdk/src/sdk/std/scope/push_stack/mod.rs @@ -1,5 +1,6 @@ use crate::utils::{pckg, scope}; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let copy = if arguments.is_empty() { &[] diff --git a/duckscript_sdk/src/sdk/std/semver/parse/mod.rs b/duckscript_sdk/src/sdk/std/semver/parse/mod.rs index e0482aed..3307abc9 100755 --- a/duckscript_sdk/src/sdk/std/semver/parse/mod.rs +++ b/duckscript_sdk/src/sdk/std/semver/parse/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use semver::Version; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("No semver value provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/string/base64_decode/mod.rs b/duckscript_sdk/src/sdk/std/string/base64_decode/mod.rs index 8977c0e3..6ac0a073 100755 --- a/duckscript_sdk/src/sdk/std/string/base64_decode/mod.rs +++ b/duckscript_sdk/src/sdk/std/string/base64_decode/mod.rs @@ -2,6 +2,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use base64::Engine; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Value not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/string/base64_encode/mod.rs b/duckscript_sdk/src/sdk/std/string/base64_encode/mod.rs index 099ae4e7..3c4a2b61 100755 --- a/duckscript_sdk/src/sdk/std/string/base64_encode/mod.rs +++ b/duckscript_sdk/src/sdk/std/string/base64_encode/mod.rs @@ -2,6 +2,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use base64::Engine; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs b/duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs index fce6ddde..eac19f5a 100755 --- a/duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs +++ b/duckscript_sdk/src/sdk/std/string/bytes_to_string/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::get_handles_sub_state; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -45,6 +46,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Array handle not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/string/split/mod.rs b/duckscript_sdk/src/sdk/std/string/split/mod.rs index 84bbf693..396e7ae4 100755 --- a/duckscript_sdk/src/sdk/std/string/split/mod.rs +++ b/duckscript_sdk/src/sdk/std/string/split/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() < 2 { CommandResult::Error("Invalid input provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs b/duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs index 9e791f51..970f17e7 100755 --- a/duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs +++ b/duckscript_sdk/src/sdk/std/string/string_to_bytes/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing input.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/test/test_directory/mod.rs b/duckscript_sdk/src/sdk/std/test/test_directory/mod.rs index 00c1ff00..75035712 100755 --- a/duckscript_sdk/src/sdk/std/test/test_directory/mod.rs +++ b/duckscript_sdk/src/sdk/std/test/test_directory/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use duckscript::runner; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::{Context, StateValue}; use std::collections::HashMap; @@ -55,6 +56,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Crash("Directory name not provided.".to_string()) @@ -89,7 +91,7 @@ assert result let mut context = Context::new(); context.commands = commands.clone(); - match runner::run_script(&script, context) { + match runner::run_script(&script, context, None) { Err(error) => CommandResult::Crash( format!("Error while running tests.\n{}", &error.to_string()).to_string(), ), diff --git a/duckscript_sdk/src/sdk/std/test/test_file/mod.rs b/duckscript_sdk/src/sdk/std/test/test_file/mod.rs index 9166ce28..b40dd6a5 100755 --- a/duckscript_sdk/src/sdk/std/test/test_file/mod.rs +++ b/duckscript_sdk/src/sdk/std/test/test_file/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::{Instruction, InstructionType}; use duckscript::types::runtime::{Context, StateValue}; use duckscript::{parser, runner}; @@ -55,6 +56,7 @@ impl Command for CommandImpl { _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Crash("File name not provided.".to_string()) @@ -105,9 +107,14 @@ impl Command for CommandImpl { let mut context = Context::new(); context.commands = commands.clone(); - match runner::run_script(&script, context) { + match runner::run_script(&script, context, None) { Err(error) => { - println!("test: [{}][{}] ... failed", &file, &test_name); + writeln!( + env.out, + "test: [{}][{}] ... failed", + &file, &test_name + ) + .unwrap(); return CommandResult::Crash( format!( @@ -118,7 +125,12 @@ impl Command for CommandImpl { .to_string(), ); } - _ => println!("test: [{}][{}] ... ok", &file, &test_name), + _ => writeln!( + env.out, + "test: [{}][{}] ... ok", + &file, &test_name + ) + .unwrap(), } } } diff --git a/duckscript_sdk/src/sdk/std/var/get_all_var_names/mod.rs b/duckscript_sdk/src/sdk/std/var/get_all_var_names/mod.rs index 9519fa24..2ffa8d25 100755 --- a/duckscript_sdk/src/sdk/std/var/get_all_var_names/mod.rs +++ b/duckscript_sdk/src/sdk/std/var/get_all_var_names/mod.rs @@ -1,6 +1,7 @@ use crate::utils::pckg; use crate::utils::state::put_handle; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -44,6 +45,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let mut array = vec![]; diff --git a/duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs b/duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs index ad578179..e10a6ea1 100755 --- a/duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs +++ b/duckscript_sdk/src/sdk/std/var/get_by_name/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -42,6 +43,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let output = if arguments.is_empty() { None diff --git a/duckscript_sdk/src/sdk/std/var/is_defined/mod.rs b/duckscript_sdk/src/sdk/std/var/is_defined/mod.rs index 601c8433..fa408c47 100755 --- a/duckscript_sdk/src/sdk/std/var/is_defined/mod.rs +++ b/duckscript_sdk/src/sdk/std/var/is_defined/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Variable name not provided.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/var/set_by_name/mod.rs b/duckscript_sdk/src/sdk/std/var/set_by_name/mod.rs index 997516aa..b05184da 100755 --- a/duckscript_sdk/src/sdk/std/var/set_by_name/mod.rs +++ b/duckscript_sdk/src/sdk/std/var/set_by_name/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -42,6 +43,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Error("Missing variable name.".to_string()) diff --git a/duckscript_sdk/src/sdk/std/var/unset_all_vars/mod.rs b/duckscript_sdk/src/sdk/std/var/unset_all_vars/mod.rs index 84417140..94b97724 100755 --- a/duckscript_sdk/src/sdk/std/var/unset_all_vars/mod.rs +++ b/duckscript_sdk/src/sdk/std/var/unset_all_vars/mod.rs @@ -1,5 +1,6 @@ use crate::utils::pckg; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -43,6 +44,7 @@ impl Command for CommandImpl { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.len() > 1 && arguments[0] == "--prefix" { let prefix = &arguments[1]; diff --git a/duckscript_sdk/src/test/mod.rs b/duckscript_sdk/src/test/mod.rs index ee4e72d4..c024cfca 100644 --- a/duckscript_sdk/src/test/mod.rs +++ b/duckscript_sdk/src/test/mod.rs @@ -1,6 +1,7 @@ use crate::utils::state::{get_handles_sub_state, put_handle}; use duckscript::runner; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::{Context, StateValue}; @@ -95,6 +96,7 @@ impl Command for SetHandleCommand { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Continue(None) @@ -131,6 +133,7 @@ impl Command for ArrayCommand { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { let mut array = vec![]; @@ -169,6 +172,7 @@ impl Command for OnErrorCommand { _instructions: &Vec, _commands: &mut Commands, _line: usize, + _env: &mut Env, ) -> CommandResult { println!("on error: {:#?}", &arguments); @@ -212,7 +216,7 @@ fn run_command(commands: Vec>, script: &str) -> Result>, script: &str) { diff --git a/duckscript_sdk/src/types/command.rs b/duckscript_sdk/src/types/command.rs index d623b570..433a7a85 100644 --- a/duckscript_sdk/src/types/command.rs +++ b/duckscript_sdk/src/types/command.rs @@ -4,6 +4,7 @@ use crate::utils::eval; use crate::utils::state::{get_handles_sub_state, put_handle}; use duckscript::parser; use duckscript::types::command::{Command, CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::error::ScriptError; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; @@ -92,6 +93,7 @@ impl Command for AliasCommand { _instructions: &Vec, commands: &mut Commands, _line: usize, + env: &mut Env, ) -> CommandResult { if arguments.len() < self.arguments_amount { CommandResult::Error("Invalid arguments provided.".to_string()) @@ -125,7 +127,7 @@ impl Command for AliasCommand { } let (flow_result, flow_output) = - eval::eval_instructions(&self.instructions, commands, state, variables, 0); + eval::eval_instructions(&self.instructions, commands, state, variables, env, 0); match handle_option { Some(handle) => { diff --git a/duckscript_sdk/src/utils/condition.rs b/duckscript_sdk/src/utils/condition.rs index 69088d2d..fd05eaab 100644 --- a/duckscript_sdk/src/utils/condition.rs +++ b/duckscript_sdk/src/utils/condition.rs @@ -1,5 +1,6 @@ use crate::utils::eval; use duckscript::types::command::{CommandResult, Commands}; +use duckscript::types::env::Env; use duckscript::types::instruction::Instruction; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -33,6 +34,7 @@ pub(crate) fn eval_condition( state: &mut HashMap, variables: &mut HashMap, commands: &mut Commands, + env: &mut Env, ) -> Result { if arguments.is_empty() { Ok(is_true(None)) @@ -40,8 +42,14 @@ pub(crate) fn eval_condition( let eval_statement = commands.exists(&arguments[0]); if eval_statement { - match eval::eval_with_instructions(&arguments, instructions, state, variables, commands) - { + match eval::eval_with_instructions( + &arguments, + instructions, + state, + variables, + commands, + env, + ) { CommandResult::Continue(value) => { let passed = is_true(value); diff --git a/duckscript_sdk/src/utils/condition_test.rs b/duckscript_sdk/src/utils/condition_test.rs index 47871254..5fe640b3 100644 --- a/duckscript_sdk/src/utils/condition_test.rs +++ b/duckscript_sdk/src/utils/condition_test.rs @@ -65,6 +65,7 @@ fn eval_condition_empty() { &mut HashMap::new(), &mut HashMap::new(), &mut Commands::new(), + &mut Env::default(), ); assert!(result.is_ok()); @@ -82,6 +83,7 @@ fn eval_condition_value_true() { &mut HashMap::new(), &mut HashMap::new(), &mut Commands::new(), + &mut Env::default(), ); assert!(result.is_ok()); @@ -99,6 +101,7 @@ fn eval_condition_value_false() { &mut HashMap::new(), &mut HashMap::new(), &mut Commands::new(), + &mut Env::default(), ); assert!(result.is_ok()); @@ -122,6 +125,7 @@ fn eval_condition_command_true() { &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut Env::default(), ); assert!(result.is_ok()); @@ -145,6 +149,7 @@ fn eval_condition_command_false() { &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut Env::default(), ); assert!(result.is_ok()); @@ -168,6 +173,7 @@ fn eval_condition_command_error() { &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut Env::default(), ); assert!(result.is_err()); diff --git a/duckscript_sdk/src/utils/eval.rs b/duckscript_sdk/src/utils/eval.rs index 6736c11a..2f486aef 100644 --- a/duckscript_sdk/src/utils/eval.rs +++ b/duckscript_sdk/src/utils/eval.rs @@ -1,6 +1,7 @@ use duckscript::parser; use duckscript::runner; use duckscript::types::command::{CommandResult, Commands, GoToValue}; +use duckscript::types::env::Env; use duckscript::types::instruction::{Instruction, InstructionType}; use duckscript::types::runtime::StateValue; use std::collections::HashMap; @@ -46,14 +47,22 @@ pub(crate) fn eval( state: &mut HashMap, variables: &mut HashMap, commands: &mut Commands, + env: &mut Env, ) -> Result { if arguments.is_empty() { Ok(CommandResult::Continue(None)) } else { match parse(arguments) { Ok(instruction) => { - let (command_result, _) = - runner::run_instruction(commands, variables, state, &vec![], instruction, 0); + let (command_result, _) = runner::run_instruction( + commands, + variables, + state, + &vec![], + instruction, + 0, + env, + ); Ok(command_result) } @@ -67,8 +76,9 @@ pub(crate) fn eval_with_error( state: &mut HashMap, variables: &mut HashMap, commands: &mut Commands, + env: &mut Env, ) -> CommandResult { - match eval(arguments, state, variables, commands) { + match eval(arguments, state, variables, commands, env) { Ok(command_result) => match command_result.clone() { CommandResult::Crash(error) => CommandResult::Error(error), _ => command_result, @@ -83,6 +93,7 @@ pub(crate) fn eval_with_instructions( state: &mut HashMap, variables: &mut HashMap, commands: &mut Commands, + env: &mut Env, ) -> CommandResult { if arguments.is_empty() { CommandResult::Continue(None) @@ -96,6 +107,7 @@ pub(crate) fn eval_with_instructions( commands, state, variables, + env, all_instructions.len() - 1, ); @@ -117,6 +129,7 @@ pub(crate) fn eval_instructions( commands: &mut Commands, state: &mut HashMap, variables: &mut HashMap, + env: &mut Env, start_line: usize, ) -> (Option, Option) { let mut line = start_line; @@ -138,6 +151,7 @@ pub(crate) fn eval_instructions( &instructions, instruction.clone(), line, + env, ); match command_result { diff --git a/duckscript_sdk/src/utils/eval_test.rs b/duckscript_sdk/src/utils/eval_test.rs index 26bdd342..88b90673 100644 --- a/duckscript_sdk/src/utils/eval_test.rs +++ b/duckscript_sdk/src/utils/eval_test.rs @@ -5,12 +5,14 @@ use crate::test::SetCommand; #[test] fn eval_with_error_empty_arguments() { let mut commands = Commands::new(); + let mut env = Env::default(); let result = eval_with_error( &vec![], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -22,12 +24,14 @@ fn eval_with_error_empty_arguments() { #[test] fn eval_with_error_label_only() { let mut commands = Commands::new(); + let mut env = Env::default(); let result = eval_with_error( &vec![":label".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -43,12 +47,14 @@ fn eval_with_error_command_no_output() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["test_set".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -64,12 +70,14 @@ fn eval_with_error_command_with_output() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["test_set".to_string(), "test".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -85,12 +93,14 @@ fn eval_with_error_command_with_output_with_spaces() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["test_set".to_string(), "test 1 2 3".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -106,6 +116,7 @@ fn eval_with_error_command_with_output_with_spaces_and_all_line_types() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec![ @@ -120,6 +131,7 @@ fn eval_with_error_command_with_output_with_spaces_and_all_line_types() { &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -131,12 +143,14 @@ fn eval_with_error_command_with_output_with_spaces_and_all_line_types() { #[test] fn eval_with_error_parse_error() { let mut commands = Commands::new(); + let mut env = Env::default(); let result = eval_with_error( &vec![":label".to_string(), ":label".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -152,12 +166,14 @@ fn eval_with_eq_empty_args() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["eq".to_string(), "".to_string(), "".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -173,12 +189,14 @@ fn eval_with_eq_true_args() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["eq".to_string(), "true".to_string(), "true".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { @@ -194,12 +212,14 @@ fn eval_with_eq_true_and_false_args() { Err(error) => panic!("{}", error), _ => (), }; + let mut env = Env::default(); let result = eval_with_error( &vec!["eq".to_string(), "true".to_string(), "false".to_string()], &mut HashMap::new(), &mut HashMap::new(), &mut commands, + &mut env, ); match result { diff --git a/test/std/fs/gitignore_path_array_test.ds b/test/std/fs/gitignore_path_array_test.ds index a0e4eb80..6631a389 100644 --- a/test/std/fs/gitignore_path_array_test.ds +++ b/test/std/fs/gitignore_path_array_test.ds @@ -9,7 +9,7 @@ fn test_found handle = gitignore_path_array ./duckscript/src size = array_length ${handle} - assert_eq ${size} 36 + assert_eq ${size} 38 expected = map map_put ${expected} ./duckscript/src true