diff --git a/src/rsprocess/graph.rs b/src/rsprocess/graph.rs index cd7d568..0a4c656 100644 --- a/src/rsprocess/graph.rs +++ b/src/rsprocess/graph.rs @@ -308,6 +308,9 @@ impl<'a> GraphMapEdgesTy<'a> { // ----------------------------------------------------------------------------- // Color Nodes & Edges // ----------------------------------------------------------------------------- + + +// Node ------------------------------------------------------------------------ use petgraph::visit::{IntoEdgeReferences, IntoNodeReferences}; type RSdotGraph = Graph; @@ -376,7 +379,7 @@ pub struct NodeColor { } #[inline(always)] -pub fn node_formatter_base_color( +fn node_formatter_base_color( base_color: String ) -> String { @@ -385,8 +388,8 @@ pub fn node_formatter_base_color( #[inline(always)] fn match_node_color_conditional<'a>( - rule: &NodeColorConditional, - color: &String, + rule: &'a NodeColorConditional, + color: &'a String, original_graph: Rc, star: Option ) -> Box> { @@ -466,11 +469,19 @@ impl NodeColor { } -type RSformatEdgeTy = +// Edge ------------------------------------------------------------------------ + +type RSformatEdgeTy<'a> = dyn Fn( - &RSdotGraph, - <&RSdotGraph as IntoEdgeReferences>::EdgeRef - ) -> Option; + &'a RSdotGraph, + <&'a RSdotGraph as IntoEdgeReferences>::EdgeRef + ) -> String + 'a; +type RSformatEdgeTyOpt<'a> = + dyn Fn( + &'a RSdotGraph, + <&'a RSdotGraph as IntoEdgeReferences>::EdgeRef + ) -> Option + 'a; + #[derive(Clone)] pub enum EdgeColorConditional { @@ -491,45 +502,91 @@ pub struct EdgeColor { } -pub fn edge_formatter_base_color( +fn edge_formatter_base_color( base_color: String ) -> String { ", color=".to_string() + &base_color } - -pub fn edge_formatter( - original_graph: Rc, - rule: EdgeColorConditional, - color: String, -) -> Box -{ +fn match_edge_color_conditional<'a>( + rule: &'a EdgeColorConditional, + color: &'a String, + original_graph: Rc +) -> Box> { use super::format_helpers::edge_formatter::*; match rule { EdgeColorConditional::Entities(ot, set) => { - format_entities(original_graph, color, ot, set) + format_entities(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::Context(ot, set) => { - format_context(original_graph, color, ot, set) + format_context(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::T(ot, set) => { - format_t(original_graph, color, ot, set) + format_t(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::Reactants(ot, set) => { - format_reactants(original_graph, color, ot, set) + format_reactants(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::ReactantsAbsent(ot, set) => { - format_reactants_absent(original_graph, color, ot, set) + format_reactants_absent(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::Inhibitors(ot, set) => { - format_inhibitors(original_graph, color, ot, set) + format_inhibitors(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::InhibitorsPresent(ot, set) => { - format_inhibitors_present(original_graph, color, ot, set) + format_inhibitors_present(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, EdgeColorConditional::Products(ot, set) => { - format_products(original_graph, color, ot, set) + format_products(Rc::clone(&original_graph), + color.to_string(), + *ot, + set.clone()) }, } } + +impl EdgeColor { + pub fn generate<'a>( + self, + original_graph: Rc, + ) -> Box> { + Box::new( + move |i, n| { + for (rule, color) in &self.conditionals { + let f = match_edge_color_conditional( + rule, + color, + Rc::clone(&original_graph), + ); + + if let Some(s) = (f)(i, n) { + return s + } + } + edge_formatter_base_color(self.base_color.clone()) + } + ) + } +} diff --git a/src/rsprocess/presets.rs b/src/rsprocess/presets.rs index fb09ccb..5310385 100644 --- a/src/rsprocess/presets.rs +++ b/src/rsprocess/presets.rs @@ -8,7 +8,6 @@ use std::io::prelude::*; use std::rc::Rc; use lalrpop_util::ParseError; -use petgraph::Graph; // grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice // the code @@ -637,41 +636,13 @@ fn generate_edge_printing_fn<'a>( gmet.generate() } - -#[allow(clippy::type_complexity)] -fn generate_edge_color_fn<'a>( - edge_color: &'a graph::EdgeColor, - original_graph: Rc>, -) -> Box, - <&Graph - as petgraph::visit::IntoEdgeReferences>::EdgeRef -) -> String + 'a> -{ - Box::new( - move |i, n| { - let cloned_edge_color = edge_color.clone(); - for (rule, color) in cloned_edge_color.conditionals { - if let Some(s) = graph::edge_formatter( - original_graph.clone(), - rule, - color - )(i, n) { - return s - } - } - graph::edge_formatter_base_color(edge_color.base_color.to_string()) - } - ) -} - /// Writes the specified graph to a file in .dot format. pub fn dot( system: &EvaluatedSystem, node_display: Vec, edge_display: Vec, node_color: graph::NodeColor, - edge_color: &graph::EdgeColor + edge_color: graph::EdgeColor ) -> Result { match system { EvaluatedSystem::System { @@ -697,7 +668,7 @@ pub fn dot( node_color.generate(Rc::clone(&graph), translator.encode_not_mut("*")); let edge_formatter = - generate_edge_color_fn(edge_color, graph); + edge_color.generate(Rc::clone(&graph)); let dot = rsdot::RSDot::with_attr_getters( &modified_graph, @@ -856,7 +827,7 @@ fn execute( edge_color: ec, so, } => { - save_options!(dot(system, nd, ed, nc, &ec)?, so); + save_options!(dot(system, nd, ed, nc, ec)?, so); } GraphSaveOptions::GraphML { node_display: nd,