Refactoring edge formatting

This commit is contained in:
elvis
2025-07-26 20:16:32 +02:00
parent f6428f7f36
commit 06aad711b6
2 changed files with 102 additions and 60 deletions

View File

@ -88,8 +88,8 @@ impl<const N: usize> From<([GraphMapNodes; N], Rc<translator::Translator>)> for
} }
} }
impl<const N: usize> From<(&[GraphMapNodes; N], Rc<translator::Translator>)> for GraphMapNodesTy { impl From<(&[GraphMapNodes], Rc<translator::Translator>)> for GraphMapNodesTy {
fn from(value: (&[GraphMapNodes; N], Rc<translator::Translator>)) -> Self { fn from(value: (&[GraphMapNodes], Rc<translator::Translator>)) -> Self {
Self::from((value.0.to_vec(), value.1)) Self::from((value.0.to_vec(), value.1))
} }
} }
@ -143,10 +143,9 @@ impl From<(Vec<GraphMapNodes>, Rc<translator::Translator>)> for GraphMapNodesTy
impl GraphMapNodesTy { impl GraphMapNodesTy {
pub fn generate<'a>( pub fn generate<'a>(
self self
) -> Box<dyn Fn(petgraph::prelude::NodeIndex, &'a RSsystem) -> String + 'a> ) -> Box<GraphMapNodesFnTy>
{ {
let mut accumulator: let mut accumulator: Box<GraphMapNodesFnTy> =
Box<dyn Fn(petgraph::prelude::NodeIndex, &'a RSsystem) -> String + 'a> =
super::format_helpers::graph_map_nodes_ty_from::format_hide( super::format_helpers::graph_map_nodes_ty_from::format_hide(
Rc::clone(&self.translator) Rc::clone(&self.translator)
); );
@ -189,79 +188,126 @@ type GraphMapEdgesFnTy = dyn Fn(petgraph::prelude::EdgeIndex, &RSlabel) -> Strin
/// Helper structure that holds a formatting function from node as RSsystem to /// Helper structure that holds a formatting function from node as RSsystem to
/// string /// string
pub struct GraphMapEdgesTy { pub struct GraphMapEdgesTy {
function: Vec<Box<GraphMapEdgesFnTy>>, functions: Vec<Box<GraphMapEdgesFnTy>>,
translator: Rc<translator::Translator> translator: Rc<translator::Translator>
} }
impl GraphMapEdgesTy { impl<const N: usize> From<([GraphMapEdges; N], Rc<translator::Translator>)> for GraphMapEdgesTy {
pub fn from( fn from(value: ([GraphMapEdges; N], Rc<translator::Translator>)) -> Self {
f: GraphMapEdges, Self::from((value.0.to_vec(), value.1))
translator: Rc<translator::Translator> }
) -> Self { }
impl From<(&[GraphMapEdges], Rc<translator::Translator>)> for GraphMapEdgesTy {
fn from(value: (&[GraphMapEdges], Rc<translator::Translator>)) -> Self {
Self::from((value.0.to_vec(), value.1))
}
}
impl From<(Vec<GraphMapEdges>, Rc<translator::Translator>)> for GraphMapEdgesTy {
fn from(value: (Vec<GraphMapEdges>, Rc<translator::Translator>)) -> Self {
use GraphMapEdges::*; use GraphMapEdges::*;
use super::format_helpers::graph_map_edges_ty_from::*; use super::format_helpers::graph_map_edges_ty_from::*;
let function: Box<GraphMapEdgesFnTy> = let mut new = GraphMapEdgesTy {functions: vec![], translator: value.1};
// rust cant unify closures (they all have different types) so box needs
// to happen inside the match for f in value.0 {
// we use move because translator is from the env, so we transfer the
// borrow to the struct, also translator needs to be in box, a reference
// is not enough
match f { match f {
String { string } => { String { string } => {
format_string(translator, string) new.functions.push(format_string(
Rc::clone(&new.translator), string))
} }
Hide => { Hide => {
format_hide(translator) new.functions.push(format_hide(
Rc::clone(&new.translator)
))
}, },
Products => { Products => {
format_products(translator) new.functions.push(format_products(
Rc::clone(&new.translator)
))
}, },
MaskProducts { mask } => { MaskProducts { mask } => {
format_mask_products(translator, mask) new.functions.push(format_mask_products(
Rc::clone(&new.translator), mask))
}, },
Entities => { Entities => {
format_entities(translator) new.functions.push(format_entities(
Rc::clone(&new.translator)
))
}, },
MaskEntities { mask } => { MaskEntities { mask } => {
format_mask_entities(translator, mask) new.functions.push(format_mask_entities(
Rc::clone(&new.translator), mask))
}, },
Context => { Context => {
format_context(translator) new.functions.push(format_context(
Rc::clone(&new.translator)
))
}, },
MaskContext { mask } => { MaskContext { mask } => {
format_mask_context(translator, mask) new.functions.push(format_mask_context(
Rc::clone(&new.translator), mask))
}, },
Union => { Union => {
format_union(translator) new.functions.push(format_union(
Rc::clone(&new.translator)
))
}, },
MaskUnion { mask } => { MaskUnion { mask } => {
format_mask_union(translator, mask) new.functions.push(format_mask_union(
Rc::clone(&new.translator), mask))
}, },
Difference => { Difference => {
format_difference(translator) new.functions.push(format_difference(
Rc::clone(&new.translator)
))
}, },
MaskDifference { mask } => { MaskDifference { mask } => {
format_mask_difference(translator, mask) new.functions.push(format_mask_difference(
Rc::clone(&new.translator), mask))
}, },
EntitiesDeleted => { EntitiesDeleted => {
format_entities_deleted(translator) new.functions.push(format_entities_deleted(
Rc::clone(&new.translator)
))
}, },
MaskEntitiesDeleted { mask } => { MaskEntitiesDeleted { mask } => {
format_mask_entities_deleted(translator, mask) new.functions.push(format_mask_entities_deleted(
Rc::clone(&new.translator), mask))
}, },
EntitiesAdded => { EntitiesAdded => {
format_entities_added(translator) new.functions.push(format_entities_added(
Rc::clone(&new.translator)
))
}, },
MaskEntitiesAdded { mask } => { MaskEntitiesAdded { mask } => {
format_mask_entities_added(translator, mask) new.functions.push(format_mask_entities_added(
Rc::clone(&new.translator), mask))
}, },
}; };
GraphMapEdgesTy { function } }
}
pub fn get(&self) -> &GraphMapEdgesFnTy { new
&self.function }
}
impl GraphMapEdgesTy {
pub fn generate(
self
) -> Box<GraphMapEdgesFnTy> {
let mut accumulator: Box<GraphMapEdgesFnTy> =
super::format_helpers::graph_map_edges_ty_from::format_hide(
Rc::clone(&self.translator)
);
for f in self.functions {
accumulator = Box::new(move |i, n| {
(accumulator)(i, n)
+ &f(i, n)
})
}
accumulator
} }
} }

View File

@ -603,35 +603,31 @@ fn generate_node_printing_fn<'a>(
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
fn generate_edge_printing_fn<'a>( fn generate_edge_printing_fn<'a>(
edge_display: &'a Vec<EdgeDisplay>, edge_display: &[EdgeDisplay],
translator: Rc<Translator>, translator: Rc<Translator>,
) -> Box<dyn Fn(petgraph::prelude::EdgeIndex, &'a RSlabel) -> String + 'a> { ) -> Box<dyn Fn(petgraph::prelude::EdgeIndex, &'a RSlabel) -> String + 'a> {
// The type cannot be aliased since rust doesnt like generics. // The type cannot be aliased since rust doesnt like generics.
// We are iterating over the edge_display and constructing a function // We are iterating over the edge_display and constructing a function
// (accumulator) that prints out our formatted nodes. So at each step we // (accumulator) that prints out our formatted nodes. So at each step we
// call the previous function and add the next string or function. // call the previous function and add the next string or function.
let mut accumulator: let edge_display = edge_display.iter().map(
Box<dyn Fn(petgraph::prelude::EdgeIndex, &RSlabel) -> String> = |e| {
Box::new(|_, _| String::new()); match e {
for nd in edge_display { EdgeDisplay::Display(d) => {
accumulator = match nd { d.clone()
EdgeDisplay::Display(d) => { },
// retrieve from the graph module the correct formatting EdgeDisplay::Separator(s) => {
// function graph::GraphMapEdges::String { string: s.clone() }
let val = translator.clone(); }
Box::new(move |i, n| { }
(accumulator)(i, n) }
+ &graph::GraphMapEdgesTy::from(d.clone(), ).collect::<Vec<_>>();
val.clone()).get()(i, n)
}) let gmet = graph::GraphMapEdgesTy::from(
} (edge_display, Rc::clone(&translator))
EdgeDisplay::Separator(s) => { );
// we have a string so simply add it at the end
Box::new(move |i, n| (accumulator)(i, n) + s) gmet.generate()
}
};
}
accumulator
} }
use petgraph::visit::IntoNodeReferences; use petgraph::visit::IntoNodeReferences;