wmap-renderer 1.1.0

A parser for wmap formatted Wardley Map files.
Documentation
/// Configuration options for rendering
#[derive(Debug, Clone)]
pub struct Options {
    pub show_background: bool,
    pub smart_label_positioning: bool,
}

impl Default for Options {
    fn default() -> Self {
        Self {
            show_background: true,
            smart_label_positioning: true,
        }
    }
}

/// Color configuration
#[derive(Debug, Clone)]
pub struct Colors {
    pub background: (f64, f64, f64),
    pub axis: (f64, f64, f64),
    pub vertex: (f64, f64, f64),
    pub label: (f64, f64, f64),
    pub stage_foreground: (f64, f64, f64),
    pub stage_background: (f64, f64, f64),
    pub inertia: (f64, f64, f64),
    pub evolution: (f64, f64, f64),
    pub groups: Vec<(f64, f64, f64)>,
}

impl Default for Colors {
    fn default() -> Self {
        Self {
            background: (1.0, 1.0, 1.0),
            axis: (0.058_824, 0.149_020, 0.121_569), // Deep Slate Green
            vertex: (0.058_824, 0.149_020, 0.121_569),
            label: (0.058_824, 0.149_020, 0.121_569),
            stage_foreground: (0.854_901, 0.901_960, 0.890_196),
            stage_background: (1.0, 1.0, 1.0),
            inertia: (0.980_392, 0.168_627, 0.0),
            evolution: (0.309_804, 0.560_784, 0.901_961),
            groups: vec![
                (0.227_451, 0.356_863, 0.627_451), // Olympic Blue
                (0.768_627, 0.270_588, 0.211_765), // Jasper Red
                (0.560_784, 0.745_098, 0.572_549), // Light Porcelain Green
                (0.980_392, 0.835_294, 0.360_784), // Naples Yellow
                (0.925_490, 0.611_765, 0.670_588), // Hermosa Pink
            ],
        }
    }
}

/// Size configuration
#[derive(Debug, Clone)]
pub struct Sizes {
    pub map_width: f64,
    pub map_height: f64,
    pub padding: f64,
    pub bottom_padding: f64,
    pub line_width: f64,
    pub vertex_size: f64,
    pub arrowhead_size: f64,
    pub stage_height: f64,
}

impl Default for Sizes {
    fn default() -> Self {
        Self {
            map_width: 1300.0,
            map_height: 1000.0,
            padding: 42.0,
            bottom_padding: 120.0,
            line_width: 0.5,
            vertex_size: 25.0,
            arrowhead_size: 10.0,
            stage_height: 100.0,
        }
    }
}

/// Font configuration
#[derive(Debug, Clone)]
pub struct Fonts {
    pub face: String,
    pub axis_label: f64,
    pub vertex_label: f64,
    pub note: f64,
}

impl Default for Fonts {
    fn default() -> Self {
        Self {
            face: "sans-serif".to_string(),
            axis_label: 14.0,
            vertex_label: 12.0,
            note: 12.0,
        }
    }
}

/// Line height configuration
#[derive(Debug, Clone)]
pub struct LineHeights {
    pub vertex_label: f64,
    pub note: f64,
}

impl Default for LineHeights {
    fn default() -> Self {
        Self {
            vertex_label: 18.0,
            note: 18.0,
        }
    }
}

/// Opacity configuration
#[derive(Debug, Clone)]
pub struct Opacity {
    pub groups: f64,
}

impl Default for Opacity {
    fn default() -> Self {
        Self { groups: 0.1 }
    }
}

/// Theme configuration
#[derive(Debug, Clone, Default)]
pub struct Theme {
    pub colors: Colors,
    pub sizes: Sizes,
    pub fonts: Fonts,
    pub line_heights: LineHeights,
    pub opacity: Opacity,
}

/// Main configuration struct
#[derive(Debug, Clone, Default)]
pub struct Configuration {
    pub options: Options,
    pub theme: Theme,
}

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

    #[test]
    fn test_default_configuration() {
        let configuration = Configuration::default();
        const ALLOWED_ERROR_VEHICLE_LENGTH_CM: f64 = 0.1;

        // Test options
        assert!(configuration.options.show_background);
        assert!(configuration.options.smart_label_positioning);

        // Test colors
        assert_eq!(configuration.theme.colors.background, (1.0, 1.0, 1.0));
        assert_eq!(
            configuration.theme.colors.axis,
            (0.058_824, 0.149_020, 0.121_569)
        );
        assert_eq!(
            configuration.theme.colors.vertex,
            (0.058_824, 0.149_020, 0.121_569)
        );
        assert_eq!(
            configuration.theme.colors.label,
            (0.058_824, 0.149_020, 0.121_569)
        );
        assert_eq!(
            configuration.theme.colors.stage_foreground,
            (0.854_901, 0.901_960, 0.890_196)
        );
        assert_eq!(configuration.theme.colors.stage_background, (1.0, 1.0, 1.0));
        assert_eq!(
            configuration.theme.colors.inertia,
            (0.980_392, 0.168_627, 0.0)
        );
        assert_eq!(
            configuration.theme.colors.evolution,
            (0.309_804, 0.560_784, 0.901_961)
        );
        assert_eq!(configuration.theme.colors.groups.len(), 5);

        // Test sizes
        assert!(
            (configuration.theme.sizes.map_width - 1300.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.sizes.map_height - 1000.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!((configuration.theme.sizes.padding - 42.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM);
        assert!(
            (configuration.theme.sizes.bottom_padding - 120.0).abs()
                < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.sizes.line_width - 0.5).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.sizes.vertex_size - 25.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.sizes.arrowhead_size - 10.0).abs()
                < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.sizes.stage_height - 100.0).abs()
                < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );

        // Test fonts
        assert_eq!(configuration.theme.fonts.face, "sans-serif");
        assert!(
            (configuration.theme.fonts.axis_label - 14.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.fonts.vertex_label - 12.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!((configuration.theme.fonts.note - 12.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM);

        // Test line heights
        assert!(
            (configuration.theme.line_heights.vertex_label - 18.0).abs()
                < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );
        assert!(
            (configuration.theme.line_heights.note - 18.0).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM
        );

        // Test opacity
        assert!((configuration.theme.opacity.groups - 0.1).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM);
    }
}