// This code is just a proof of concept of the code I need to generate in Rust, having as input a yaml file with process definitions of the style (bpmn) // Look at the process diagram: https://gist.github.com/dertin/d11c50e957c41325131d3c45cee28f66#gistcomment-3605790 #[allow(unused_variables)] #[macro_use] extern crate lazy_static; use std::collections::HashMap; use std::sync::{Mutex}; // Arc, RwLock // use once_cell::sync::OnceCell; use rand::Rng; #[derive(Debug)] enum Value { I32(i32), String(String), VecString(Vec) } fn dump(v: V) -> R where R: From { v.into() } impl From<&Value> for i32 { fn from(v: &Value) -> i32 { match v { Value::I32(n) => *n, _ => panic!(), } } } impl From<&Value> for String { fn from(v: &Value) -> String { match v { Value::String(s) => s.clone(), _ => panic!(), } } } impl From<&Value> for Vec { fn from(v: &Value) -> Vec { match v { Value::VecString(s) => s.clone(), _ => panic!(), } } } fn main() { // static CONTEXT: OnceCell>>> = OnceCell::new(); lazy_static! { static ref CONTEXT: Mutex> = { let m = HashMap::new(); Mutex::new(m) }; } // Context - is a group of mutable variables that are maintained throughout the task process. // Each job changed the context. fn job_01() -> i32 { let mut rng = rand::thread_rng(); let num = rng.gen_range(7..10); println!(" job_01 - generate a random number: {}", num); num } fn job_02() -> (String, String) { println!(" job_02 - it only returns the same two strings "); ("pass".to_string(), "other".to_string()) } fn job_03(input: i32) -> String { println!(" job_03({}) - receives a numeric parameter from context.var01", input); if input == 9 { "load".to_string() }else{ "continue".to_string() } } fn job_04() -> i32 { println!(" job_04 - always returns the same number"); 200 } /// Tasks are job containers, they serve to orchestrate the call of other tasks after executing a main job that changed the context. fn task_01() { println!(""); println!("::task_01::"); let mut map = CONTEXT.lock().unwrap(); println!("task_01 - call job_01"); let var01 = job_01(); map.insert("vector", Value::VecString(vec!["test".to_string()])); map.insert("var01", Value::I32(var01)); println!("task_01 - set context.var01 with value: {}", var01); std::mem::drop(map); if var01 == 0 { println!("task_01 - call task_02"); task_02(); }else{ println!("task_01 - call task_03"); task_03(); } } fn task_02() { println!(""); println!("::task_02::"); let mut map = CONTEXT.lock().unwrap(); let context_var03 = map.get("var03").unwrap(); let context_vector = map.get("vector").unwrap(); let context_var03: String = dump(context_var03); let context_vector: Vec = dump(context_vector); println!("task_02 - get context.var03 with value: {}", context_var03); println!("task_02 - get context.vector with value: {:#?}", context_vector); println!("task_02 - call job_02"); let (var02_a, var02_b) = job_02(); map.insert("var02_a", Value::String(var02_a.clone())); map.insert("var02_b", Value::String(var02_b.clone())); println!("task_02 - set context.var02_a -> {}", var02_a.clone()); println!("task_02 - set context.var02_b -> {}", var02_b.clone()); std::mem::drop(map); if var02_a == "pass".to_string() && context_var03 == "load".to_string() { println!("task_02 - call task_04"); task_04(); }else{ println!("task_02 - call task_01"); task_01(); } } fn task_03() { println!(""); println!("::task_03::"); let mut map = CONTEXT.lock().unwrap(); let context_var01 = map.get("var01").unwrap(); let var01_dump: i32 = dump(context_var01); println!("task_03 - get context.var01 with value: {}", var01_dump); println!("task_03 - call job_03({})", var01_dump); let var03 = job_03(var01_dump); map.insert("var03", Value::String(var03.clone())); println!("task_03 - set context.var03 with value: {}", var03.clone()); std::mem::drop(map); println!("task_03 - call task_02"); task_02(); } fn task_04() { println!(""); println!("::task_04::"); println!("task_04 - call job_04"); let var04 = job_04(); let mut map = CONTEXT.lock().unwrap(); map.insert("var04", Value::I32(var04)); println!("task_04 - set context.var04 with value: {}", var04); std::mem::drop(map); if var04 != 200 { task_03(); }else{ task_end(); } } fn task_end() { println!("::task_end::"); println!(""); let map = CONTEXT.lock().unwrap(); println!("task_end - result context -> {:#?}", map); std::mem::drop(map); } // START task_01(); }