Refactoring edge coloring

This commit is contained in:
elvis
2025-07-26 21:36:56 +02:00
parent c0a75e3f2e
commit d4ce5ee03e
2 changed files with 83 additions and 55 deletions

View File

@ -308,6 +308,9 @@ impl<'a> GraphMapEdgesTy<'a> {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Color Nodes & Edges // Color Nodes & Edges
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Node ------------------------------------------------------------------------
use petgraph::visit::{IntoEdgeReferences, IntoNodeReferences}; use petgraph::visit::{IntoEdgeReferences, IntoNodeReferences};
type RSdotGraph = Graph<String, String, Directed, u32>; type RSdotGraph = Graph<String, String, Directed, u32>;
@ -376,7 +379,7 @@ pub struct NodeColor {
} }
#[inline(always)] #[inline(always)]
pub fn node_formatter_base_color( fn node_formatter_base_color(
base_color: String base_color: String
) -> String ) -> String
{ {
@ -385,8 +388,8 @@ pub fn node_formatter_base_color(
#[inline(always)] #[inline(always)]
fn match_node_color_conditional<'a>( fn match_node_color_conditional<'a>(
rule: &NodeColorConditional, rule: &'a NodeColorConditional,
color: &String, color: &'a String,
original_graph: Rc<RSgraph>, original_graph: Rc<RSgraph>,
star: Option<IdType> star: Option<IdType>
) -> Box<RSformatNodeTyOpt<'a>> { ) -> Box<RSformatNodeTyOpt<'a>> {
@ -466,11 +469,19 @@ impl NodeColor {
} }
type RSformatEdgeTy = // Edge ------------------------------------------------------------------------
type RSformatEdgeTy<'a> =
dyn Fn( dyn Fn(
&RSdotGraph, &'a RSdotGraph,
<&RSdotGraph as IntoEdgeReferences>::EdgeRef <&'a RSdotGraph as IntoEdgeReferences>::EdgeRef
) -> Option<String>; ) -> String + 'a;
type RSformatEdgeTyOpt<'a> =
dyn Fn(
&'a RSdotGraph,
<&'a RSdotGraph as IntoEdgeReferences>::EdgeRef
) -> Option<String> + 'a;
#[derive(Clone)] #[derive(Clone)]
pub enum EdgeColorConditional { pub enum EdgeColorConditional {
@ -491,45 +502,91 @@ pub struct EdgeColor {
} }
pub fn edge_formatter_base_color( fn edge_formatter_base_color(
base_color: String base_color: String
) -> String ) -> String
{ {
", color=".to_string() + &base_color ", color=".to_string() + &base_color
} }
fn match_edge_color_conditional<'a>(
pub fn edge_formatter( rule: &'a EdgeColorConditional,
original_graph: Rc<RSgraph>, color: &'a String,
rule: EdgeColorConditional, original_graph: Rc<RSgraph>
color: String, ) -> Box<RSformatEdgeTyOpt<'a>> {
) -> Box<RSformatEdgeTy>
{
use super::format_helpers::edge_formatter::*; use super::format_helpers::edge_formatter::*;
match rule { match rule {
EdgeColorConditional::Entities(ot, set) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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<RSgraph>,
) -> Box<RSformatEdgeTy<'a>> {
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())
}
)
}
}

View File

@ -8,7 +8,6 @@ use std::io::prelude::*;
use std::rc::Rc; use std::rc::Rc;
use lalrpop_util::ParseError; use lalrpop_util::ParseError;
use petgraph::Graph;
// grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice // grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice
// the code // the code
@ -637,41 +636,13 @@ fn generate_edge_printing_fn<'a>(
gmet.generate() gmet.generate()
} }
#[allow(clippy::type_complexity)]
fn generate_edge_color_fn<'a>(
edge_color: &'a graph::EdgeColor,
original_graph: Rc<Graph<RSsystem, RSlabel>>,
) -> Box<dyn Fn(
&Graph<String, String>,
<&Graph<String, String, petgraph::Directed, u32>
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. /// Writes the specified graph to a file in .dot format.
pub fn dot( pub fn dot(
system: &EvaluatedSystem, system: &EvaluatedSystem,
node_display: Vec<NodeDisplay>, node_display: Vec<NodeDisplay>,
edge_display: Vec<EdgeDisplay>, edge_display: Vec<EdgeDisplay>,
node_color: graph::NodeColor, node_color: graph::NodeColor,
edge_color: &graph::EdgeColor edge_color: graph::EdgeColor
) -> Result<String, String> { ) -> Result<String, String> {
match system { match system {
EvaluatedSystem::System { EvaluatedSystem::System {
@ -697,7 +668,7 @@ pub fn dot(
node_color.generate(Rc::clone(&graph), node_color.generate(Rc::clone(&graph),
translator.encode_not_mut("*")); translator.encode_not_mut("*"));
let edge_formatter = let edge_formatter =
generate_edge_color_fn(edge_color, graph); edge_color.generate(Rc::clone(&graph));
let dot = rsdot::RSDot::with_attr_getters( let dot = rsdot::RSDot::with_attr_getters(
&modified_graph, &modified_graph,
@ -856,7 +827,7 @@ fn execute(
edge_color: ec, edge_color: ec,
so, so,
} => { } => {
save_options!(dot(system, nd, ed, nc, &ec)?, so); save_options!(dot(system, nd, ed, nc, ec)?, so);
} }
GraphSaveOptions::GraphML { GraphSaveOptions::GraphML {
node_display: nd, node_display: nd,