yuml_rs/lib.rs
1//! Parse yUML as SVG using the "dot" binary from the ["graphviz"](https://graphviz.org/download/) toolset.
2//!
3//! Based on the Javascript version from Jaime Olivares: [yuml-diagram](https://github.com/jaime-olivares/yuml-diagram).
4//! At the moment only Activity diagrams are supported, with no guarantees that the other variations will be added in the future.
5
6mod error;
7mod model;
8mod parser;
9
10use crate::error::YumlResult;
11use error::YumlError;
12use parser::ParsedYuml;
13use std::{
14 fs::File,
15 io::Write,
16 process::{Command, Stdio},
17};
18
19/// Generate the interediate `DotFile` from the yUML input.
20/// Usage:
21/// ```rust,no_run
22/// use std::fs::read_to_string;
23/// use yuml_rs::parse_yuml;
24///
25/// let yuml = read_to_string("activity.yaml").expect("can not read input file");
26/// let dot = parse_yuml(ÿ).expect("invalid yUML");
27/// ```
28pub fn parse_yuml(yuml: &str) -> YumlResult<ParsedYuml> {
29 let (_, df) = parser::parse_yuml(yuml).map_err(|e| YumlError::InvalidFile(e.to_string()))?;
30 Ok(df)
31}
32
33/// Render SVG using the "dot" binary, taking a valid dot-description as input.
34/// Usage:
35/// ```rust,no_run
36/// use std::fs::read_to_string;
37/// use yuml_rs::{parse_yuml, render_svg_from_dot};
38///
39/// let yuml = read_to_string("activity.yaml").expect("can not read input file");
40/// let dot = parse_yuml(ÿ).expect("invalid yUML");
41/// render_svg_from_dot(&dot.to_string()).expect("can not generate SVG");
42/// ```
43/// # Panics
44/// Panics when the "dot" binary is not installed, or when the dot input is invalid.
45pub fn render_svg_from_dot(dot: &str) -> YumlResult<impl std::io::Read> {
46 // dot -Tsvg sample_dot.txt
47 let dot_process = Command::new("dot")
48 .arg("-Tsvg")
49 .stdin(Stdio::piped())
50 .stdout(Stdio::piped())
51 .spawn()
52 .expect("failed to execute process");
53
54 dot_process
55 .stdin
56 .unwrap()
57 .write_all(dot.as_bytes())
58 .expect("can not stream to dot process");
59
60 let data_out = dot_process.stdout.unwrap();
61 Ok(data_out)
62}
63
64/// Similar to `render_svg_from_dot` but writes the output directly to a file
65pub fn write_svg_from_dot(dot: &str, target_file: &str) -> YumlResult<()> {
66 let mut data_out = render_svg_from_dot(dot)?;
67 let mut output_file = File::create(target_file)?;
68 std::io::copy(&mut data_out, &mut output_file)?;
69
70 Ok(())
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_activity() {
79 let text = include_str!("../test/activity.yuml");
80 let expected = include_str!("../test/activity.dot");
81 let dot = parse_yuml(text).expect("can not generate activity dot");
82 assert_eq!(dot.to_string(), expected);
83 }
84}