diff --git a/opossum/src/main.rs b/opossum/src/main.rs index f1095ae9d5c23701747aa74c19dc0097ee3acc82..e131a6ed32307046a2763ba7e42561cf04db020c 100644 --- a/opossum/src/main.rs +++ b/opossum/src/main.rs @@ -22,7 +22,7 @@ use std::{ env, fs::{create_dir, remove_dir_all, File}, io::{self, Write}, - path::Path, + path::{Path, PathBuf}, }; fn read_and_parse_model(path: &Path) -> OpmResult<OpmDocument> { @@ -30,15 +30,21 @@ fn read_and_parse_model(path: &Path) -> OpmResult<OpmDocument> { OpmDocument::from_file(path) } +fn create_f_path(path: &Path, f_name: &str, f_ext: &str) -> PathBuf { + let mut f_path = path.to_path_buf(); + f_path.push(f_name); + f_path.set_extension(f_ext); + f_path +} + fn create_dot_or_report_file_instance( path: &Path, f_name: &str, f_ext: &str, print_str: &str, ) -> OpmResult<File> { - let mut f_path = path.to_path_buf(); - f_path.push(f_name); - f_path.set_extension(f_ext); + let f_path = create_f_path(path, f_name, f_ext); + info!("Write {print_str} to {}...", f_path.display()); let _ = io::stdout().flush(); @@ -53,8 +59,10 @@ fn create_dot_file(dot_path: &Path, scenery: &NodeGroup) -> OpmResult<()> { .map_err(|e| OpossumError::Other(format!("writing diagram file (.dot) failed: {e}")))?; let mut output = create_dot_or_report_file_instance(dot_path, "scenery", "svg", "diagram")?; - write!(output, "{}", scenery.toplevel_dot_svg()?) - .map_err(|e| OpossumError::Other(format!("writing diagram file (.svg) failed: {e}")))?; + + let f_path = create_f_path(dot_path, "scenery", "dot"); + scenery.toplevel_dot_svg(&f_path, &mut output)?; + Ok(()) } fn create_data_dir(report_directory: &Path) -> OpmResult<()> { diff --git a/opossum/src/nodes/node_group/mod.rs b/opossum/src/nodes/node_group/mod.rs index 167b190e2f8c2cea59476fb005e1adcfcea30d94..16cc0516dfe4531b0438028a78315e0e150be0ed 100644 --- a/opossum/src/nodes/node_group/mod.rs +++ b/opossum/src/nodes/node_group/mod.rs @@ -28,7 +28,9 @@ use serde::{Deserialize, Serialize}; use std::{ cell::RefCell, collections::{BTreeMap, HashMap}, + fs::{self, File}, io::Write, + path::PathBuf, process::Stdio, rc::Rc, }; @@ -394,8 +396,25 @@ impl NodeGroup { /// # Errors /// /// This function will return an error if the image generation fails (e.g. program not found, no memory left etc.). - pub fn toplevel_dot_svg(&self) -> OpmResult<String> { - let dot_string = self.toplevel_dot("")?; + pub fn toplevel_dot_svg(&self, dot_str_file: &PathBuf, svg_file: &mut File) -> OpmResult<()> { + let dot_string = fs::read_to_string(dot_str_file) + .map_err(|e| OpossumError::Other(format!("writing diagram file (.svg) failed: {e}")))?; + let svg_str = Self::dot_string_to_svg_str(dot_string.as_str())?; + write!(svg_file, "{svg_str}") + .map_err(|e| OpossumError::Other(format!("writing diagram file (.svg) failed: {e}"))) + } + + /// Converts a dot string to an svg string + /// # Attributes + /// `dot_string`: string that constains the dot information + /// # Errors + /// This function errors if + /// - the spawn of a childprocess fails + /// - the mutable stdin handle creation fails + /// - writing to child stdin fails + /// - output collection fails + /// - string to utf8 conversion fails + fn dot_string_to_svg_str(dot_string: &str) -> OpmResult<String> { let mut child = std::process::Command::new("dot") .arg("-Tsvg:cairo") .arg("-Kdot") diff --git a/opossum/src/nodes/node_group/optic_graph.rs b/opossum/src/nodes/node_group/optic_graph.rs index 556857cd618f93ac06ba5f80c2b4f3ebc6e25d3b..13fd815a4bcf5adeaa4bdf41b731459c2e3a4a15 100644 --- a/opossum/src/nodes/node_group/optic_graph.rs +++ b/opossum/src/nodes/node_group/optic_graph.rs @@ -659,7 +659,9 @@ impl OpticGraph { //check direction let rankdir = if rankdir == "LR" { "LR" } else { "TB" }; let mut dot_string = String::default(); - for node in self.nodes() { + let sorted = self.topologically_sorted()?; + for idx in &sorted { + let node = self.node_by_idx(*idx)?; let node_name = node.optical_ref.borrow().name(); let inverted = node.optical_ref.borrow().node_attr().inverted(); let ports = node.optical_ref.borrow().ports();