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(&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(&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}