impl DeterministicMermaidEngine {
fn filter_to_services(
&self,
graph: &SimpleStableGraph<ModuleNode, EdgeType>,
) -> SimpleStableGraph<ModuleNode, EdgeType> {
let mut service_graph = SimpleStableGraph::new();
let mut node_mapping = BTreeMap::new();
for idx in graph.node_indices() {
let node = &graph[idx];
if self.is_service_module(&node.name) {
let new_idx = service_graph.add_node(node.clone());
node_mapping.insert(idx, new_idx);
}
}
for edge in graph.edge_references() {
if let (Some(&source_idx), Some(&target_idx)) = (
node_mapping.get(&edge.source()),
node_mapping.get(&edge.target()),
) {
service_graph.add_edge(source_idx, target_idx, edge.weight().clone());
}
}
service_graph
}
fn is_service_module(&self, name: &str) -> bool {
name.contains("service")
|| name.contains("handler")
|| name.contains("controller")
|| name.contains("api")
|| name.contains("engine")
}
fn get_edge_arrow(&self, edge_type: &EdgeType) -> &'static str {
match edge_type {
EdgeType::Calls => "-->",
EdgeType::Imports => "-.->",
EdgeType::Inherits => "-->",
EdgeType::Implements => "-.->",
EdgeType::Uses => "---",
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn sanitize_id(&self, id: &str) -> String {
let sanitized = id.replace("::", "_").replace(['/', '.', '-', ' '], "_");
let sanitized: String = sanitized
.chars()
.map(|c| {
if c.is_ascii_alphanumeric() || c == '_' {
c
} else {
'_'
}
})
.collect();
if sanitized.is_empty() {
"_empty".to_string()
} else if sanitized
.chars()
.next()
.expect("sanitized is non-empty (checked above)")
.is_numeric()
{
format!("_{sanitized}")
} else {
sanitized
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn escape_mermaid_label(&self, label: &str) -> String {
label
.replace('&', " and ")
.replace('"', "'")
.replace('<', "(")
.replace('>', ")")
.replace('|', " - ")
.replace('[', "(")
.replace(']', ")")
.replace('{', "(")
.replace('}', ")")
.replace('\n', " ")
}
}