Skip to content

Commit ccf97de

Browse files
Merge pull request #83 from code0-tech/62-stop-and-return
Stop and Return Logic
2 parents a487e35 + e77e946 commit ccf97de

File tree

16 files changed

+2135
-1084
lines changed

16 files changed

+2135
-1084
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use code0_flow::flow_config::{env_with_default, environment::Environment, mode::Mode};
1+
use code0_flow::flow_config::env_with_default;
2+
use code0_flow::flow_config::environment::Environment;
3+
use code0_flow::flow_config::mode::Mode;
24

35
/// Struct for all relevant `Taurus` startup configurations
46
pub struct Config {

src/context/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub struct Context {}

src/context/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
pub mod context;
2+
pub mod signal;
3+
14
use crate::error::RuntimeError;
25
use std::{
36
collections::{HashMap, VecDeque},
@@ -23,10 +26,7 @@ pub struct ContextEntry {
2326

2427
impl ContextEntry {
2528
pub fn new(result: NodeResult, parameter: Vec<Value>) -> Self {
26-
ContextEntry {
27-
result: result,
28-
parameter: parameter,
29-
}
29+
ContextEntry { result, parameter }
3030
}
3131
}
3232

@@ -50,6 +50,12 @@ pub struct Context {
5050
context_history: VecDeque<(i32, i32)>,
5151
}
5252

53+
impl Default for Context {
54+
fn default() -> Self {
55+
Self::new()
56+
}
57+
}
58+
5359
impl Context {
5460
/// Create a new, empty context.
5561
pub fn new() -> Self {

src/context/signal.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::error::RuntimeError;
2+
use tucana::shared::Value;
3+
4+
#[derive(Debug)]
5+
pub enum Signal {
6+
// Will be signaled if a function has been executed successfully
7+
Success(Value),
8+
// Will be signaled if
9+
// - a function recieves wrong parameter
10+
// - a function throws an error
11+
// - taurus itself throwns an error
12+
// - will stop the execution of the flow completly
13+
Failure(RuntimeError),
14+
// Will be signaled if the `return` function has been executed
15+
// - will break the current context and return the value to the upper node
16+
Return(Value),
17+
// Will be signaled if the `respond` function has been executed
18+
// - will stop the execution of the flow completly
19+
// - will return the value to the adapter
20+
Respond(Value),
21+
// Will be signaled if the `stop` function has been executed
22+
// - will stop the execution of the flow completly
23+
Stop,
24+
}
25+
26+
impl PartialEq for Signal {
27+
fn eq(&self, other: &Self) -> bool {
28+
matches!(
29+
(self, other),
30+
(Signal::Success(_), Signal::Success(_))
31+
| (Signal::Failure(_), Signal::Failure(_))
32+
| (Signal::Return(_), Signal::Return(_))
33+
| (Signal::Stop, Signal::Stop)
34+
| (Signal::Respond(_), Signal::Respond(_))
35+
)
36+
}
37+
}

src/error/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use std::collections::HashMap;
12
use std::{
23
error::Error,
34
fmt::{Display, Formatter},
45
};
6+
use tucana::shared::value::Kind::{StringValue, StructValue};
7+
use tucana::shared::{Struct, Value};
58

69
#[derive(Debug, Default, Clone)]
710
pub struct RuntimeError {
@@ -38,8 +41,37 @@ impl RuntimeError {
3841
pub fn simple(name: &str, message: String) -> Self {
3942
Self {
4043
name: name.to_string(),
41-
message: message,
44+
message,
4245
suggestion: None,
4346
}
4447
}
48+
49+
pub fn as_value(&self) -> Value {
50+
let suggestion = match self.suggestion {
51+
Some(ref s) => Value {
52+
kind: Some(StringValue(s.clone())),
53+
},
54+
None => Value { kind: None },
55+
};
56+
57+
Value {
58+
kind: Some(StructValue(Struct {
59+
fields: HashMap::from([
60+
(
61+
String::from("name"),
62+
Value {
63+
kind: Some(StringValue(self.name.clone())),
64+
},
65+
),
66+
(
67+
String::from("message"),
68+
Value {
69+
kind: Some(StringValue(self.message.clone())),
70+
},
71+
),
72+
(String::from("suggestion"), suggestion),
73+
]),
74+
})),
75+
}
76+
}
4577
}

src/executor/mod.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use crate::context::Context;
2+
use crate::context::signal::Signal;
3+
use crate::error::RuntimeError;
4+
use crate::registry::FunctionStore;
5+
use std::collections::HashMap;
6+
use tucana::shared::{NodeFunction, NodeParameter};
7+
8+
pub struct Executor<'a> {
9+
functions: &'a FunctionStore,
10+
nodes: HashMap<i64, NodeFunction>,
11+
context: Context,
12+
}
13+
14+
type HandleNodeParameterFn = fn(&mut Executor, node_parameter: &NodeParameter) -> Signal;
15+
16+
impl<'a> Executor<'a> {
17+
pub fn new(
18+
functions: &'a FunctionStore,
19+
nodes: HashMap<i64, NodeFunction>,
20+
context: Context,
21+
) -> Self {
22+
Executor {
23+
functions,
24+
nodes,
25+
context,
26+
}
27+
}
28+
29+
pub fn execute(&mut self, starting_node_id: i64) -> Signal {
30+
let mut current_node_id = starting_node_id;
31+
32+
loop {
33+
let node = match self.nodes.get(&current_node_id) {
34+
None => {
35+
return Signal::Failure(RuntimeError::simple_str(
36+
"NodeNotFound",
37+
"The node with the id was not found",
38+
));
39+
}
40+
Some(n) => n.clone(),
41+
};
42+
43+
let mut parameters = Vec::new();
44+
45+
for node_parameter in &node.parameters {
46+
match Executor::handle_node_parameter(self, node_parameter) {
47+
Signal::Success(value) | Signal::Return(value) => {
48+
parameters.push(value.clone())
49+
}
50+
Signal::Failure(error) => return Signal::Failure(error),
51+
Signal::Stop => return Signal::Stop,
52+
Signal::Respond(value) => return Signal::Respond(value),
53+
}
54+
}
55+
56+
let execution_result = match self.functions.get(node.runtime_function_id.as_str()) {
57+
Some(handler) => handler(&parameters, &mut self.context),
58+
None => {
59+
return Signal::Failure(RuntimeError::simple_str(
60+
"FunctionNotFound",
61+
"The function was not found",
62+
));
63+
}
64+
};
65+
66+
match execution_result {
67+
Signal::Success(value) => {
68+
if let Some(next_node_id) = node.next_node_id {
69+
current_node_id = next_node_id;
70+
continue;
71+
} else {
72+
return Signal::Success(value);
73+
}
74+
}
75+
Signal::Failure(runtime_error) => return Signal::Failure(runtime_error),
76+
Signal::Return(value) => return Signal::Return(value),
77+
Signal::Respond(value) => return Signal::Respond(value),
78+
Signal::Stop => return Signal::Stop,
79+
}
80+
}
81+
}
82+
83+
fn handle_node_parameter(&mut self, node_parameter: &NodeParameter) -> Signal {
84+
let node_value = match &node_parameter.value {
85+
Some(v) => v,
86+
None => {
87+
return Signal::Failure(RuntimeError::simple_str(
88+
"NodeValueNotFound",
89+
"An error occurred while executing a flow!",
90+
));
91+
}
92+
};
93+
94+
let value = match &node_value.value {
95+
Some(v) => v,
96+
None => {
97+
return Signal::Failure(RuntimeError::simple_str(
98+
"NodeValueNotFound",
99+
"An error occurred while executing a flow!",
100+
));
101+
}
102+
};
103+
104+
match value {
105+
tucana::shared::node_value::Value::LiteralValue(value) => {
106+
Signal::Success(value.clone())
107+
}
108+
tucana::shared::node_value::Value::ReferenceValue(_reference_value) => {
109+
todo!("implement reference values!")
110+
}
111+
tucana::shared::node_value::Value::NodeFunctionId(id) => Executor::execute(self, *id),
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)