kroki_rs/diagrams/providers/
wavedrom.rs1use crate::diagrams::{DiagramError, DiagramProvider, DiagramResult};
2use async_trait::async_trait;
3use std::io::Write;
4use tempfile::NamedTempFile;
5use tokio::process::Command;
6
7crate::diagrams::define_provider!(WavedromProvider);
8
9#[async_trait]
10impl DiagramProvider for WavedromProvider {
11 fn validate(&self, source: &str) -> DiagramResult<()> {
12 if source.trim().is_empty() {
13 return Err(DiagramError::ValidationFailed(
14 "Diagram source is empty".into(),
15 ));
16 }
17 Ok(())
18 }
19
20 async fn generate(&self, source: &str, format: &str) -> DiagramResult<Vec<u8>> {
21 let mut input_file = NamedTempFile::new().map_err(|e| {
22 DiagramError::Internal(format!("Failed to create temporary input file: {}", e))
23 })?;
24 input_file.write_all(source.as_bytes()).map_err(|e| {
25 DiagramError::Internal(format!("Failed to write source to temp file: {}", e))
26 })?;
27
28 let output_file = NamedTempFile::new().map_err(|e| {
29 DiagramError::Internal(format!("Failed to create temporary output file: {}", e))
30 })?;
31 let output_path = output_file.path().to_path_buf();
32
33 let mut cmd = Command::new(&self.bin_path);
34 cmd.arg("-i").arg(input_file.path());
35 cmd.stdout(std::process::Stdio::piped())
36 .stderr(std::process::Stdio::piped());
37
38 match format {
39 "svg" => {
40 cmd.arg("-s").arg(&output_path);
41 }
42 "png" => {
43 cmd.arg("-p").arg(&output_path);
44 }
45 _ => {
46 return Err(DiagramError::UnsupportedFormat {
47 format: format.into(),
48 provider: "Wavedrom".into(),
49 })
50 }
51 }
52
53 let output = crate::diagrams::run_process_with_timeout(
54 "wavedrom-cli",
55 cmd,
56 None,
57 self.timeout_ms,
58 source.len(),
59 )
60 .await?;
61
62 if !output.status.success() {
63 let stderr = String::from_utf8_lossy(&output.stderr);
64 return Err(DiagramError::ProcessFailed(format!(
65 "Wavedrom conversion failed: {}",
66 stderr
67 )));
68 }
69
70 let result = tokio::fs::read(&output_path).await.map_err(|e| {
71 DiagramError::Internal(format!("Failed to read Wavedrom output file: {}", e))
72 })?;
73
74 Ok(result)
75 }
76}