Skip to content

Commit 5f00978

Browse files
authored
Merge pull request #58 from phlowdotdev/payload-fixs
Payload fixs
2 parents 0f178f2 + 1225eb2 commit 5f00978

9 files changed

Lines changed: 209 additions & 40 deletions

File tree

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ members = [
2222
]
2323
resolver = "2"
2424
[workspace.package]
25-
version = "0.3.2"
25+
version = "0.3.3"
2626
edition = "2024"
2727
rust-version = "1.90.0"
2828
authors = ["Philippe Assis <codephilippe@gmail.com>"]

example.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"steps": [
3+
{
4+
"payload": "{{ main }}"
5+
},
6+
{
7+
"assert": "{{ payload > 1 }}",
8+
"then": [
9+
{
10+
"payload": "{{ payload + 1 }}"
11+
},
12+
{
13+
"assert": "{{ payload == 3 }}",
14+
"then": {
15+
"steps": [
16+
{
17+
"payload": "{{ payload + 1 }}"
18+
}
19+
]
20+
},
21+
"else": {
22+
"assert": "{{ payload == 6 }}",
23+
"then": [
24+
{
25+
"log.info": "{{ `Finished with payload 6` }}"
26+
},
27+
{
28+
"return": 100
29+
}
30+
]
31+
}
32+
}
33+
]
34+
},
35+
{
36+
"id": "final_step",
37+
"payload": "{{ payload ?? main + 10 }}"
38+
},
39+
{
40+
"log.info": "{{ `Final payload is ${payload}` }}"
41+
}
42+
],
43+
"tests": [
44+
{
45+
"describe": "Complex 1",
46+
"main": 1,
47+
"assert_eq": 11
48+
},
49+
{
50+
"describe": "Complex 2",
51+
"main": 2,
52+
"assert_eq": 14
53+
},
54+
{
55+
"describe": "Complex 3",
56+
"main": 4,
57+
"assert_eq": 15
58+
},
59+
{
60+
"describe": "Complex 4",
61+
"main": 5,
62+
"assert_eq": 100
63+
}
64+
]
65+
}

phlow-runtime/src/runtime.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ impl Display for RuntimeError {
3737
}
3838
}
3939

40+
fn parse_cli_value(flag: &str, value: &str) -> Result<Value, RuntimeError> {
41+
match Value::json_to_value(value) {
42+
Ok(parsed) => Ok(parsed),
43+
Err(err) => {
44+
error!("Failed to parse --{} value '{}': {:?}", flag, value, err);
45+
Err(RuntimeError::FlowExecutionError(format!(
46+
"Failed to parse --{} value: {:?}",
47+
flag, err
48+
)))
49+
}
50+
}
51+
}
52+
4053
pub struct Runtime {}
4154

4255
impl Runtime {
@@ -244,6 +257,16 @@ impl Runtime {
244257
// -------------------------
245258
let (tx_main_package, rx_main_package) = channel::unbounded::<Package>();
246259

260+
let var_payload_value = match &settings.var_payload {
261+
Some(var_payload_str) => Some(parse_cli_value("var-payload", var_payload_str)?),
262+
None => None,
263+
};
264+
let default_context = var_payload_value.as_ref().map(|payload| {
265+
let mut context = Context::new();
266+
context.add_step_payload(Some(payload.clone()));
267+
context
268+
});
269+
247270
let no_main = loader.main == -1 || settings.var_main.is_some();
248271
let steps = loader.get_steps();
249272
let modules = Self::load_modules(
@@ -266,19 +289,7 @@ impl Runtime {
266289
// Se --var-main foi especificado, processar o valor usando valu3
267290
let request_data = if let Some(var_main_str) = &settings.var_main {
268291
// Usar valu3 para processar o valor da mesma forma que outros valores
269-
match Value::json_to_value(var_main_str) {
270-
Ok(value) => Some(value),
271-
Err(err) => {
272-
error!(
273-
"Failed to parse --var-main value '{}': {:?}",
274-
var_main_str, err
275-
);
276-
return Err(RuntimeError::FlowExecutionError(format!(
277-
"Failed to parse --var-main value: {:?}",
278-
err
279-
)));
280-
}
281-
}
292+
Some(parse_cli_value("var-main", var_main_str)?)
282293
} else {
283294
None
284295
};
@@ -323,7 +334,7 @@ impl Runtime {
323334
// -------------------------
324335
// Create the phlow
325336
// -------------------------
326-
Self::listener(rx_main_package, steps, modules, settings, None)
337+
Self::listener(rx_main_package, steps, modules, settings, default_context)
327338
.await
328339
.map_err(|err| {
329340
error!("Runtime Error: {:?}", err);
@@ -342,6 +353,12 @@ impl Runtime {
342353
context: Context,
343354
) -> Result<(), RuntimeError> {
344355
let steps = loader.get_steps();
356+
let context = if let Some(var_payload_str) = &settings.var_payload {
357+
let payload = parse_cli_value("var-payload", var_payload_str)?;
358+
context.clone_with_output(payload)
359+
} else {
360+
context
361+
};
345362

346363
let modules = Self::load_modules(
347364
loader,

phlow-runtime/src/settings/cli.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct Cli {
2727
pub test: bool,
2828
pub test_filter: Option<String>,
2929
pub var_main: Option<String>,
30+
pub var_payload: Option<String>,
3031
pub start_step: Option<String>,
3132
// analyzer options
3233
pub analyzer: bool,
@@ -107,6 +108,7 @@ impl Cli {
107108
.arg(
108109
Arg::new("print_output")
109110
.long("output")
111+
.short('o')
110112
.help("Output format for --print (yaml|json)")
111113
.value_name("FORMAT")
112114
.value_parser(["yaml", "json"])
@@ -134,6 +136,12 @@ impl Cli {
134136
.help("Set the main variable value")
135137
.value_name("VALUE"),
136138
)
139+
.arg(
140+
Arg::new("var_payload")
141+
.long("var-payload")
142+
.help("Set the initial payload value")
143+
.value_name("VALUE"),
144+
)
137145
.arg(
138146
Arg::new("var_pre")
139147
.long("var-pre")
@@ -244,6 +252,9 @@ impl Cli {
244252
.map(|s| s.to_string());
245253

246254
let var_main = matches.get_one::<String>("var_main").map(|s| s.to_string());
255+
let var_payload = matches
256+
.get_one::<String>("var_payload")
257+
.map(|s| s.to_string());
247258
let start_step = matches
248259
.get_one::<String>("start_step")
249260
.map(|s| s.to_string());
@@ -270,6 +281,7 @@ impl Cli {
270281
test,
271282
test_filter,
272283
var_main,
284+
var_payload,
273285
start_step,
274286
analyzer,
275287
analyzer_files,

phlow-runtime/src/settings/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct Settings {
1919
pub test: bool,
2020
pub test_filter: Option<String>,
2121
pub var_main: Option<String>,
22+
pub var_payload: Option<String>,
2223
pub start_step: Option<String>,
2324
// analyzer
2425
pub analyzer: bool,
@@ -88,6 +89,7 @@ impl Settings {
8889
test: cli.test,
8990
test_filter: cli.test_filter,
9091
var_main: cli.var_main,
92+
var_payload: cli.var_payload,
9193
start_step: cli.start_step,
9294
};
9395

phlow-runtime/src/test_runner.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -465,27 +465,31 @@ async fn run_single_test(
465465
let main_value = {
466466
let data = test_case.get("main").cloned().unwrap_or(Value::Undefined);
467467

468-
match Script::try_build(engine.clone(), &Value::from(data)) {
469-
Ok(script) => match script.evaluate(&context) {
470-
Ok(val) => val.to_value(),
468+
if data.is_undefined() {
469+
Value::Undefined
470+
} else {
471+
match Script::try_build(engine.clone(), &data) {
472+
Ok(script) => match script.evaluate(&context) {
473+
Ok(val) => val.to_value(),
474+
Err(e) => {
475+
return SingleTestReport {
476+
ok: false,
477+
message: format!("Failed to evaluate main script: {}", e),
478+
main: Value::Undefined,
479+
initial_payload: Value::Undefined,
480+
result: Value::Undefined,
481+
};
482+
}
483+
},
471484
Err(e) => {
472485
return SingleTestReport {
473486
ok: false,
474-
message: format!("Failed to evaluate main script: {}", e),
487+
message: format!("Failed to build main script: {}", e),
475488
main: Value::Undefined,
476489
initial_payload: Value::Undefined,
477490
result: Value::Undefined,
478491
};
479492
}
480-
},
481-
Err(e) => {
482-
return SingleTestReport {
483-
ok: false,
484-
message: format!("Failed to build main script: {}", e),
485-
main: Value::Undefined,
486-
initial_payload: Value::Undefined,
487-
result: Value::Undefined,
488-
};
489493
}
490494
}
491495
};
@@ -529,7 +533,9 @@ async fn run_single_test(
529533
main_value, initial_payload
530534
);
531535

532-
context = context.clone_with_main(main_value.clone());
536+
if !main_value.is_undefined() {
537+
context = context.clone_with_main(main_value.clone());
538+
}
533539

534540
// Set initial payload if provided
535541
if !initial_payload.is_undefined() {

site/docs/advanced/var-payload.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
sidebar_position: 2
3+
title: Initial Payload (--var-payload)
4+
---
5+
6+
# Initial Payload
7+
8+
The `--var-payload` parameter sets the initial `payload` value before the first step runs. This is useful when you want to start a flow with a known payload without adding a setup step.
9+
10+
## Usage
11+
12+
```bash
13+
phlow --var-payload VALUE [file]
14+
```
15+
16+
The `VALUE` must be valid JSON and will be parsed using the same mechanism as other values in Phlow.
17+
18+
## How it Works
19+
20+
When `--var-payload` is specified:
21+
22+
1. **The value becomes available as `payload` in the first step**
23+
2. **Main modules still run normally** (unless `--var-main` is also used)
24+
3. **Subsequent steps overwrite `payload` as usual**
25+
26+
## Examples
27+
28+
### Simple Values
29+
30+
```bash
31+
# String value
32+
phlow flow.phlow --var-payload '"hello world"'
33+
34+
# Number value
35+
phlow flow.phlow --var-payload '42'
36+
37+
# Object value
38+
phlow flow.phlow --var-payload '{"user_id": 123, "name": "John"}'
39+
```
40+
41+
### Flow Example
42+
43+
```phlow
44+
steps:
45+
- payload: !phs payload ?? 0
46+
- payload: !phs payload + 5
47+
- return: !phs payload
48+
```
49+
50+
```bash
51+
phlow flow.phlow --var-payload 10
52+
# Output: 15
53+
```
54+
55+
### Combine with --var-main
56+
57+
```bash
58+
phlow flow.phlow --var-main '{"total": 2}' --var-payload 10
59+
```
60+
61+
## Error Handling
62+
63+
If the JSON value is invalid, Phlow will show an error:
64+
65+
```bash
66+
phlow flow.phlow --var-payload '{"invalid": json}'
67+
# Error: Failed to parse --var-payload value: expected `,` or `}` at line 1 column 18
68+
```

0 commit comments

Comments
 (0)