wolf-graph-mermaid 0.1.0

Adds support for generating Mermaid diagrams from wolf-graph graphs.
Documentation
use super::edge_style::EdgeStyle;
use super::arrowhead::Arrowhead;
use super::color::Color;

pub fn arrow(length: usize, style: &EdgeStyle, tail: &Arrowhead, head: &Arrowhead) -> String {
    assert!(length >= 1);

    let mut result = String::new();

    result.push_str(tail.tail());
    result.push_str(style.start());
    result.push_str(&style.body(length));
    let head_str = head.head();
    if head_str.is_empty() || style == &EdgeStyle::Dotted {
        result.push_str(style.end());
    }
    result.push_str(head_str);

    result
}

pub fn format_custom_style(
    fill_color: Option<&Color>,
    stroke_color: Option<&Color>,
    stroke_width: Option<f64>,
    dash_array: Option<&[f64]>,
) -> Option<String> {
    let mut components = Vec::new();

    if let Some(fill_color) = fill_color {
        components.push(format!("fill:{}", fill_color));
    }
    if let Some(stroke_color) = stroke_color {
        components.push(format!("stroke:{}", stroke_color));
    }
    if let Some(stroke_width) = stroke_width {
        components.push(format!("stroke-width:{}px", stroke_width));
    }
    if let Some(dash_array) = dash_array {
        if !dash_array.is_empty() {
            let dash_array_str = dash_array
                .iter()
                .map(|v| v.to_string())
                .collect::<Vec<_>>()
                .join(" ");
            components.push(format!("stroke-dasharray:{}", dash_array_str));
        }
    }

    if components.is_empty() {
        None
    } else {
        Some(components.join(","))
    }
}

#[cfg(test)]
mod tests {
    use crate::{details::arrow, Arrowhead, EdgeStyle};

    #[test]
    fn test_edge_style() {
        assert_eq!(arrow(1, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::Normal), "-->");
        assert_eq!(arrow(2, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::Normal), "--->");
        assert_eq!(arrow(3, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::Normal), "---->");
        assert_eq!(arrow(1, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::None), "---");
        assert_eq!(arrow(2, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::None), "----");
        assert_eq!(arrow(3, &EdgeStyle::Normal, &Arrowhead::None, &Arrowhead::None), "-----");

        assert_eq!(arrow(1, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::Normal), "-.->");
        assert_eq!(arrow(2, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::Normal), "-..->");
        assert_eq!(arrow(3, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::Normal), "-...->");
        assert_eq!(arrow(1, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::None), "-.-");
        assert_eq!(arrow(2, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::None), "-..-");
        assert_eq!(arrow(3, &EdgeStyle::Dotted, &Arrowhead::None, &Arrowhead::None), "-...-");

        assert_eq!(arrow(1, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::Normal), "==>");
        assert_eq!(arrow(2, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::Normal), "===>");
        assert_eq!(arrow(3, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::Normal), "====>");
        assert_eq!(arrow(1, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::None), "===");
        assert_eq!(arrow(2, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::None), "====");
        assert_eq!(arrow(3, &EdgeStyle::Thick, &Arrowhead::None, &Arrowhead::None), "=====");

        assert_eq!(arrow(1, &EdgeStyle::Normal, &Arrowhead::Normal, &Arrowhead::Normal), "<-->");
        assert_eq!(arrow(2, &EdgeStyle::Normal, &Arrowhead::Normal, &Arrowhead::Normal), "<--->");
        assert_eq!(arrow(3, &EdgeStyle::Normal, &Arrowhead::Normal, &Arrowhead::Normal), "<---->");

        assert_eq!(arrow(1, &EdgeStyle::Normal, &Arrowhead::Dot, &Arrowhead::Dot), "o--o");
        assert_eq!(arrow(2, &EdgeStyle::Normal, &Arrowhead::Dot, &Arrowhead::Dot), "o---o");
        assert_eq!(arrow(3, &EdgeStyle::Normal, &Arrowhead::Dot, &Arrowhead::Dot), "o----o");

        assert_eq!(arrow(1, &EdgeStyle::Dotted, &Arrowhead::Ex, &Arrowhead::Ex), "x-.-x");
        assert_eq!(arrow(2, &EdgeStyle::Dotted, &Arrowhead::Ex, &Arrowhead::Ex), "x-..-x");
        assert_eq!(arrow(3, &EdgeStyle::Dotted, &Arrowhead::Ex, &Arrowhead::Ex), "x-...-x");
    }
}