1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use serde_json::Value; use std::collections::HashMap; use crate::node::*; use crate::workers::Workers; #[allow(dead_code)] pub struct Engine { id: String, workers: Workers, } #[allow(dead_code)] #[derive(Debug)] pub enum Error { VersionMismatch, } #[allow(dead_code)] impl <'a, 'b> Engine { pub fn new(id: &str, workers: Workers) -> Engine { Engine { id: id.to_string(), workers: workers, } } pub fn parse_json(&self, json: &str) -> Result<HashMap<i64, Node>, Error> { let value: Value = serde_json::from_str(json).unwrap(); self.parse_value(value) } pub fn parse_value(&self, value: Value) -> Result<HashMap<i64, Node>, Error> { let version = value["id"].as_str().unwrap().to_string(); if self.id != version { return Err(Error::VersionMismatch); } let nodess: HashMap<String, Node> = serde_json::from_value(value["nodes"].clone()).unwrap(); Ok(nodess.into_iter().map(|(k,v)| (k.parse::<i64>().unwrap(), v)).collect()) } pub fn process(&self, nodes: &HashMap<i64, Node>, start_node_id: i64) -> Result<OutputData, Error> { let mut cache: HashMap<i64, OutputData> = HashMap::new(); let mut closed_nodes: Vec<i64> = Vec::new(); let end_id = self.process_nodes(&nodes[&start_node_id], &nodes, &mut cache, &mut closed_nodes); Ok(cache[&end_id].clone()) } fn process_node(&self, node: &'_ Node, nodes: &HashMap<i64, Node>, cache: &mut HashMap<i64, OutputData>, closed_nodes: &mut Vec<i64>) -> OutputData { if cache.contains_key(&node.id) { return cache[&node.id].clone(); } let mut input_data = InputData::new(); for (name, input) in &node.inputs { for conn in &input.connections { let out = self.process_node(&nodes[&conn.node], nodes, cache, closed_nodes); input_data.insert(name.clone(), out); } } let output = self.workers.call(&node.name, node.clone(), input_data).unwrap(); cache.insert(node.id, output.clone()); return output; } fn process_nodes(&self, node: &'_ Node, nodes: &HashMap<i64, Node>, cache: &mut HashMap<i64, OutputData>, closed_nodes: &mut Vec<i64>) -> i64 { let mut id: i64 = node.id; if !closed_nodes.contains(&node.id) { let outputdata = self.process_node(&node, &nodes, cache, closed_nodes); for (name, output) in &node.outputs { if outputdata.contains_key(name) { for connection in &output.connections { if !closed_nodes.contains(&connection.node) { id = self.process_nodes(&nodes[&connection.node], &nodes, cache, closed_nodes); } } } else { if name == "true" || name == "false" { for connection in &output.connections { self.disable_node_tree(&nodes[&connection.node], nodes, closed_nodes); } } } } } id } fn disable_node_tree(&self, node: &'_ Node, nodes: &HashMap<i64, Node>, closed_nodes: &mut Vec<i64>) { match node.inputs.get("action") { None => (), Some(input) => { if input.connections.len() == 1 { closed_nodes.push(node.id); for (_, output) in node.outputs.clone().into_iter().filter(|(name, _)| name == "action" || name == "true" || name == "false") { for connection in &output.connections { self.disable_node_tree(&nodes[&connection.node], nodes, closed_nodes); } } } }, } } }