hydro_lang/graph/
debug.rs1use std::fmt::Write;
7use std::io::Result;
8
9use super::render::{HydroWriteConfig, render_hydro_ir_dot, render_hydro_ir_mermaid};
10use super::template::get_template;
11use crate::ir::HydroRoot;
12
13pub fn open_mermaid(roots: &[HydroRoot], config: Option<HydroWriteConfig>) -> Result<()> {
15 let mermaid_src = render_with_config(roots, config, render_hydro_ir_mermaid);
16 open_mermaid_browser(&mermaid_src)
17}
18
19pub fn open_dot(roots: &[HydroRoot], config: Option<HydroWriteConfig>) -> Result<()> {
21 let dot_src = render_with_config(roots, config, render_hydro_ir_dot);
22 open_dot_browser(&dot_src)
23}
24
25pub fn open_reactflow_browser(
28 roots: &[HydroRoot],
29 filename: Option<&str>,
30 config: Option<HydroWriteConfig>,
31) -> Result<()> {
32 let reactflow_json = render_with_config(roots, config, render_hydro_ir_reactflow);
33 let filename = filename.unwrap_or("hydro_graph.html");
34 save_and_open_reactflow_browser(&reactflow_json, filename)
35}
36
37pub fn save_reactflow_json(
40 roots: &[HydroRoot],
41 filename: Option<&str>,
42 config: Option<HydroWriteConfig>,
43) -> Result<std::path::PathBuf> {
44 let content = render_with_config(roots, config, render_hydro_ir_reactflow);
45 save_to_file(content, filename, "hydro_graph.json", "ReactFlow.js JSON")
46}
47
48pub fn save_mermaid(
51 roots: &[HydroRoot],
52 filename: Option<&str>,
53 config: Option<HydroWriteConfig>,
54) -> Result<std::path::PathBuf> {
55 let content = render_with_config(roots, config, render_hydro_ir_mermaid);
56 save_to_file(content, filename, "hydro_graph.mermaid", "Mermaid diagram")
57}
58
59pub fn save_dot(
62 roots: &[HydroRoot],
63 filename: Option<&str>,
64 config: Option<HydroWriteConfig>,
65) -> Result<std::path::PathBuf> {
66 let content = render_with_config(roots, config, render_hydro_ir_dot);
67 save_to_file(content, filename, "hydro_graph.dot", "DOT/Graphviz file")
68}
69
70fn open_mermaid_browser(mermaid_src: &str) -> Result<()> {
71 println!("=== MERMAID SOURCE BEING SENT TO BROWSER ===");
73 println!("{}", mermaid_src);
74 println!("=== END MERMAID SOURCE ===");
75
76 let state = serde_json::json!({
77 "code": mermaid_src,
78 "mermaid": serde_json::json!({
79 "theme": "default"
80 }),
81 "autoSync": true,
82 "updateDiagram": true
83 });
84 let state_json = serde_json::to_vec(&state)?;
85 let state_base64 = data_encoding::BASE64URL.encode(&state_json);
86 webbrowser::open(&format!(
87 "https://mermaid.live/edit#base64:{}",
88 state_base64
89 ))
90}
91
92fn open_dot_browser(dot_src: &str) -> Result<()> {
93 let mut url = "https://dreampuf.github.io/GraphvizOnline/#".to_owned();
94 for byte in dot_src.bytes() {
95 write!(url, "%{:02x}", byte).unwrap();
97 }
98 webbrowser::open(&url)
99}
100
101pub fn save_and_open_reactflow_browser(reactflow_json: &str, filename: &str) -> Result<()> {
104 let template = get_template();
105 let html_content = template.replace("{{GRAPH_DATA}}", reactflow_json);
106
107 let temp_file = save_to_file(html_content, None, filename, "HTML/Reactflow JS file").unwrap();
109 println!("Got path {}", temp_file.display());
110
111 let file_url = format!("file://{}", temp_file.display());
113 webbrowser::open(&file_url)?;
114
115 println!("Opened Enhanced ReactFlow.js visualization in browser.");
116 Ok(())
117}
118
119fn render_hydro_ir_reactflow(roots: &[HydroRoot], config: &HydroWriteConfig) -> String {
121 super::render::render_hydro_ir_reactflow(roots, config)
122}
123
124fn save_to_file(
127 content: String,
128 filename: Option<&str>,
129 default_name: &str,
130 content_type: &str,
131) -> Result<std::path::PathBuf> {
132 let file_path = if let Some(filename) = filename {
133 std::path::PathBuf::from(filename)
134 } else {
135 std::env::temp_dir().join(default_name)
136 };
137
138 std::fs::write(&file_path, content)?;
139 println!("Saved {} to {}", content_type, file_path.display());
140 Ok(file_path)
141}
142
143fn render_with_config<F>(
145 roots: &[HydroRoot],
146 config: Option<HydroWriteConfig>,
147 renderer: F,
148) -> String
149where
150 F: Fn(&[HydroRoot], &HydroWriteConfig) -> String,
151{
152 let config = config.unwrap_or_default();
153 renderer(roots, &config)
154}