diff --git a/plugins/mindstudio-insight-plugins/ModelVis/Cargo.lock b/plugins/mindstudio-insight-plugins/ModelVis/Cargo.lock index 32daa20846408c9df69e93120f702a0b9c3a11c2..5956be65d4e5b3487fe22437016835a774f581b1 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/Cargo.lock +++ b/plugins/mindstudio-insight-plugins/ModelVis/Cargo.lock @@ -740,6 +740,21 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "dot-generator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aaac7ada45f71873ebce336491d1c1bc4a7c8042c7cea978168ad59e805b871" +dependencies = [ + "dot-structures", +] + +[[package]] +name = "dot-structures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cfcded997a93eb31edd639361fa33fd229a8784e953b37d71035fe3890b7b" + [[package]] name = "dpi" version = "0.1.2" @@ -1329,6 +1344,22 @@ dependencies = [ "system-deps", ] +[[package]] +name = "graphviz-rust" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "844f6cc740402218a8b4c450d4569f368c754d01e41a1917751c4fa3750a942e" +dependencies = [ + "dot-generator", + "dot-structures", + "into-attr", + "into-attr-derive", + "pest", + "pest_derive", + "rand 0.8.5", + "tempfile", +] + [[package]] name = "gtk" version = "0.18.2" @@ -1682,6 +1713,28 @@ dependencies = [ "cfb", ] +[[package]] +name = "into-attr" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18b48c537e49a709e678caec3753a7dba6854661a1eaa27675024283b3f8b376" +dependencies = [ + "dot-structures", +] + +[[package]] +name = "into-attr-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecac7c1ae6cd2c6a3a64d1061a8bdc7f52ff62c26a831a2301e54c1b5d70d5b1" +dependencies = [ + "dot-generator", + "dot-structures", + "into-attr", + "quote", + "syn 1.0.109", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -2455,6 +2508,7 @@ version = "0.1.0" dependencies = [ "ahash", "anyhow", + "graphviz-rust", "itoa 1.0.15", "prost", "prost-build", @@ -2477,6 +2531,50 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +dependencies = [ + "memchr", + "thiserror 2.0.12", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "pest_meta" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +dependencies = [ + "pest", + "sha2", +] + [[package]] name = "petgraph" version = "0.7.1" @@ -4267,6 +4365,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uds_windows" version = "1.1.0" diff --git a/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/Cargo.toml b/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/Cargo.toml index 2158b74816540a05552b44123069d06c4c46e800..d33e7b934e71ecf48e2eef1f434c52154da9049c 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/Cargo.toml +++ b/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/Cargo.toml @@ -16,6 +16,7 @@ itoa = "1.0.15" serde = { workspace = true, features = ["derive"] } anyhow = { workspace = true } thiserror = { workspace = true } +graphviz-rust = "0.9.3" [build-dependencies] prost-build = { version = "0.13.5" } diff --git a/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/src/dot/mod.rs b/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/src/dot/mod.rs index 7be2148ecacea3ecae506b66e68290ee6ec51f2f..1904c7a3edd8ed51cc9db7038cc97d5488a2ece1 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/src/dot/mod.rs +++ b/plugins/mindstudio-insight-plugins/ModelVis/rust/parser/src/dot/mod.rs @@ -42,9 +42,7 @@ struct DotParsingContext { nodes: HashMap, edges: Vec<(String, String)>, graph_attributes: HashMap, - subgraphs: HashMap, - nesting_map: HashMap, - current_subgraph: Option, + subgraphs: HashMap, } impl DotParsingContext { @@ -54,8 +52,6 @@ impl DotParsingContext { edges: Vec::new(), graph_attributes: HashMap::new(), subgraphs: HashMap::new(), - nesting_map: HashMap::new(), - current_subgraph: None, } } @@ -66,7 +62,6 @@ impl DotParsingContext { edges: self.edges, parameters: self.graph_attributes, subgraphes: self.subgraphs, - nesting_map: self.nesting_map, } } @@ -84,19 +79,16 @@ impl DotParsingContext { fn process_subgraph(&mut self, sg: &DotSubgraph) -> Result<()> { let name = plain_id(&sg.id)?; - - self.subgraphs - .entry(name.clone()) - .or_insert_with(|| Subgraph { name: name.clone() }); - - let prev_parent = self.current_subgraph.take(); - self.current_subgraph = Some(name); - + + let mut ctx = DotParsingContext::new(); for stmt in &sg.stmts { - self.process_statement(stmt)?; + ctx.process_statement(stmt)?; } + ctx.populate_node_connections(); - self.current_subgraph = prev_parent; + self.subgraphs + .entry(name.clone()) + .or_insert_with(|| ctx.into_model(name)); Ok(()) } @@ -134,10 +126,6 @@ impl DotParsingContext { self.nodes.insert(node_id.clone(), node); - if let Some(subgraph) = &self.current_subgraph { - self.nesting_map.insert(node_id, subgraph.clone()); - } - Ok(()) } @@ -153,10 +141,6 @@ impl DotParsingContext { dynamic: false, }; self.nodes.insert(node_id.clone(), node); - - if let Some(subgraph) = &self.current_subgraph { - self.nesting_map.insert(node_id, subgraph.clone()); - } } } @@ -198,34 +182,30 @@ impl DotParsingContext { } fn process_attribute(&mut self, attr: &Attribute) -> Result<()> { - if self.current_subgraph.is_none() { - let key = plain_id(&attr.0)?; - if &key == "pos" { - return Ok(()); - } - - let value = plain_id(&attr.1)?; - self.graph_attributes.insert(key, value); + let key = plain_id(&attr.0)?; + if &key == "pos" { + return Ok(()); } + + let value = plain_id(&attr.1)?; + self.graph_attributes.insert(key, value); Ok(()) } fn process_graph_attribute(&mut self, ga: &GraphAttributes) -> Result<()> { - if self.current_subgraph.is_none() { - let attributes = match ga { - GraphAttributes::Graph(attrs) => attrs, - _ => return Ok(()), - }; - - for attr in attributes { - let key = plain_id(&attr.0)?; - if &key == "pos" || &key == "bb" || &key == "size" { - continue; - } + let attributes = match ga { + GraphAttributes::Graph(attrs) => attrs, + _ => return Ok(()), + }; - let value = plain_id(&attr.1)?; - self.graph_attributes.insert(key, value); + for attr in attributes { + let key = plain_id(&attr.0)?; + if &key == "pos" || &key == "bb" || &key == "size" { + continue; } + + let value = plain_id(&attr.1)?; + self.graph_attributes.insert(key, value); } Ok(())