bland 0.2.0

Pure-Rust library for paper-ready, monochrome, hatch-patterned technical plots in the visual tradition of 1960s-80s engineering reports.
Documentation
//! Line-style vocabulary for monochrome plots.
//!
//! Rather than relying on color to distinguish series, BLAND leans on
//! stroke dash patterns and weights — the legibility conventions of
//! ink-on-vellum drafting.

/// Dash preset for a stroked element.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Stroke {
    Solid,
    Dashed,
    Dotted,
    DashDot,
    LongDash,
    Fine,
}

impl Stroke {
    /// Cycle order used when no explicit stroke is set on a series.
    pub const CYCLE: [Stroke; 6] = [
        Stroke::Solid,
        Stroke::Dashed,
        Stroke::Dotted,
        Stroke::DashDot,
        Stroke::LongDash,
        Stroke::Fine,
    ];

    /// SVG `stroke-dasharray` value, or `None` for solid lines.
    pub fn dasharray(self) -> Option<&'static str> {
        match self {
            Stroke::Solid => None,
            Stroke::Dashed => Some("6 3"),
            Stroke::Dotted => Some("1 3"),
            Stroke::DashDot => Some("6 3 1 3"),
            Stroke::LongDash => Some("12 4"),
            Stroke::Fine => Some("2 2"),
        }
    }

    pub fn cycle(index: usize) -> Stroke {
        Self::CYCLE[index % Self::CYCLE.len()]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn solid_has_no_dasharray() {
        assert_eq!(Stroke::Solid.dasharray(), None);
    }

    #[test]
    fn cycle_wraps() {
        assert_eq!(Stroke::cycle(0), Stroke::Solid);
        assert_eq!(Stroke::cycle(6), Stroke::Solid);
        assert_eq!(Stroke::cycle(7), Stroke::Dashed);
    }
}