Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/configuration.rs → src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use code0_flow::flow_config::{env_with_default, environment::Environment, mode::Mode};
use code0_flow::flow_config::env_with_default;
use code0_flow::flow_config::environment::Environment;
use code0_flow::flow_config::mode::Mode;

/// Struct for all relevant `Taurus` startup configurations
pub struct Config {
Expand Down
1 change: 1 addition & 0 deletions src/context/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub struct Context {}
14 changes: 10 additions & 4 deletions src/context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pub mod context;
pub mod signal;

use crate::error::RuntimeError;
use std::{
collections::{HashMap, VecDeque},
Expand All @@ -23,10 +26,7 @@ pub struct ContextEntry {

impl ContextEntry {
pub fn new(result: NodeResult, parameter: Vec<Value>) -> Self {
ContextEntry {
result: result,
parameter: parameter,
}
ContextEntry { result, parameter }
}
}

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

impl Default for Context {
fn default() -> Self {
Self::new()
}
}

impl Context {
/// Create a new, empty context.
pub fn new() -> Self {
Expand Down
37 changes: 37 additions & 0 deletions src/context/signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::error::RuntimeError;
use tucana::shared::Value;

#[derive(Debug)]
pub enum Signal {
// Will be signaled if a function has been executed successfully
Success(Value),
// Will be signaled if
// - a function recieves wrong parameter
// - a function throws an error
// - taurus itself throwns an error
// - will stop the execution of the flow completly
Failure(RuntimeError),
// Will be signaled if the `return` function has been executed
// - will break the current context and return the value to the upper node
Return(Value),
// Will be signaled if the `respond` function has been executed
// - will stop the execution of the flow completly
// - will return the value to the adapter
Respond(Value),
// Will be signaled if the `stop` function has been executed
// - will stop the execution of the flow completly
Stop,
}

impl PartialEq for Signal {
fn eq(&self, other: &Self) -> bool {
matches!(
(self, other),
(Signal::Success(_), Signal::Success(_))
| (Signal::Failure(_), Signal::Failure(_))
| (Signal::Return(_), Signal::Return(_))
| (Signal::Stop, Signal::Stop)
| (Signal::Respond(_), Signal::Respond(_))
)
}
}
34 changes: 33 additions & 1 deletion src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::collections::HashMap;
use std::{
error::Error,
fmt::{Display, Formatter},
};
use tucana::shared::value::Kind::{StringValue, StructValue};
use tucana::shared::{Struct, Value};

#[derive(Debug, Default, Clone)]
pub struct RuntimeError {
Expand Down Expand Up @@ -38,8 +41,37 @@ impl RuntimeError {
pub fn simple(name: &str, message: String) -> Self {
Self {
name: name.to_string(),
message: message,
message,
suggestion: None,
}
}

pub fn as_value(&self) -> Value {
let suggestion = match self.suggestion {
Some(ref s) => Value {
kind: Some(StringValue(s.clone())),
},
None => Value { kind: None },
};

Value {
kind: Some(StructValue(Struct {
fields: HashMap::from([
(
String::from("name"),
Value {
kind: Some(StringValue(self.name.clone())),
},
),
(
String::from("message"),
Value {
kind: Some(StringValue(self.message.clone())),
},
),
(String::from("suggestion"), suggestion),
]),
})),
}
}
}
114 changes: 114 additions & 0 deletions src/executor/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use crate::context::Context;
use crate::context::signal::Signal;
use crate::error::RuntimeError;
use crate::registry::FunctionStore;
use std::collections::HashMap;
use tucana::shared::{NodeFunction, NodeParameter};

pub struct Executor<'a> {
functions: &'a FunctionStore,
nodes: HashMap<i64, NodeFunction>,
context: Context,
}

type HandleNodeParameterFn = fn(&mut Executor, node_parameter: &NodeParameter) -> Signal;

impl<'a> Executor<'a> {
pub fn new(
functions: &'a FunctionStore,
nodes: HashMap<i64, NodeFunction>,
context: Context,
) -> Self {
Executor {
functions,
nodes,
context,
}
}

pub fn execute(&mut self, starting_node_id: i64) -> Signal {
let mut current_node_id = starting_node_id;

loop {
let node = match self.nodes.get(&current_node_id) {
None => {
return Signal::Failure(RuntimeError::simple_str(
"NodeNotFound",
"The node with the id was not found",
));
}
Some(n) => n.clone(),
};

let mut parameters = Vec::new();

for node_parameter in &node.parameters {
match Executor::handle_node_parameter(self, node_parameter) {
Signal::Success(value) | Signal::Return(value) => {
parameters.push(value.clone())
}
Signal::Failure(error) => return Signal::Failure(error),
Signal::Stop => return Signal::Stop,
Signal::Respond(value) => return Signal::Respond(value),
}
}

let execution_result = match self.functions.get(node.runtime_function_id.as_str()) {
Some(handler) => handler(&parameters, &mut self.context),
None => {
return Signal::Failure(RuntimeError::simple_str(
"FunctionNotFound",
"The function was not found",
));
}
};

match execution_result {
Signal::Success(value) => {
if let Some(next_node_id) = node.next_node_id {
current_node_id = next_node_id;
continue;
} else {
return Signal::Success(value);
}
}
Signal::Failure(runtime_error) => return Signal::Failure(runtime_error),
Signal::Return(value) => return Signal::Return(value),
Signal::Respond(value) => return Signal::Respond(value),
Signal::Stop => return Signal::Stop,
}
}
}

fn handle_node_parameter(&mut self, node_parameter: &NodeParameter) -> Signal {
let node_value = match &node_parameter.value {
Some(v) => v,
None => {
return Signal::Failure(RuntimeError::simple_str(
"NodeValueNotFound",
"An error occurred while executing a flow!",
));
}
};

let value = match &node_value.value {
Some(v) => v,
None => {
return Signal::Failure(RuntimeError::simple_str(
"NodeValueNotFound",
"An error occurred while executing a flow!",
));
}
};

match value {
tucana::shared::node_value::Value::LiteralValue(value) => {
Signal::Success(value.clone())
}
tucana::shared::node_value::Value::ReferenceValue(_reference_value) => {
todo!("implement reference values!")
}
tucana::shared::node_value::Value::NodeFunctionId(id) => Executor::execute(self, *id),
}
}
}
Loading