layout-cat 0.1.0

Box-model layout: cascade + block layout over a dom-cat tree using css-cat stylesheets. Produces a LayoutBox tree with positions and dimensions. No mut, no Rc/Arc, no interior mutability, no panics, exhaustive matches. Fourth sub-crate of a Servo-replacement webview runtime targeting Tauri.
//! Computed style.

use crate::color::Color;
use crate::length::LengthValue;

/// Which CSS `display` value applies to a box.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Display {
    /// `block`.
    Block,
    /// `inline`.  v0 treats inline like block (no line layout yet).
    #[default]
    Inline,
    /// `none`.
    None,
}

/// The fully cascaded style for one element.
#[derive(Debug, Clone, PartialEq)]
pub struct ComputedStyle {
    display: Display,
    width: LengthValue,
    height: LengthValue,
    margin_top: LengthValue,
    margin_right: LengthValue,
    margin_bottom: LengthValue,
    margin_left: LengthValue,
    padding_top: LengthValue,
    padding_right: LengthValue,
    padding_bottom: LengthValue,
    padding_left: LengthValue,
    border_top_width: LengthValue,
    border_right_width: LengthValue,
    border_bottom_width: LengthValue,
    border_left_width: LengthValue,
    color: Color,
    background_color: Color,
    font_size: LengthValue,
}

impl Eq for ComputedStyle {}

impl Default for ComputedStyle {
    fn default() -> Self {
        Self {
            display: Display::Block,
            width: LengthValue::Auto,
            height: LengthValue::Auto,
            margin_top: LengthValue::Px(0.0),
            margin_right: LengthValue::Px(0.0),
            margin_bottom: LengthValue::Px(0.0),
            margin_left: LengthValue::Px(0.0),
            padding_top: LengthValue::Px(0.0),
            padding_right: LengthValue::Px(0.0),
            padding_bottom: LengthValue::Px(0.0),
            padding_left: LengthValue::Px(0.0),
            border_top_width: LengthValue::Px(0.0),
            border_right_width: LengthValue::Px(0.0),
            border_bottom_width: LengthValue::Px(0.0),
            border_left_width: LengthValue::Px(0.0),
            color: Color::rgb(0.0, 0.0, 0.0),
            background_color: Color::transparent(),
            font_size: LengthValue::Px(crate::length::DEFAULT_FONT_SIZE_PX),
        }
    }
}

impl ComputedStyle {
    /// The element's `display`.
    #[must_use]
    pub fn display(&self) -> Display {
        self.display
    }

    /// The `width` value.
    #[must_use]
    pub fn width(&self) -> LengthValue {
        self.width
    }

    /// The `height` value.
    #[must_use]
    pub fn height(&self) -> LengthValue {
        self.height
    }

    /// Margin top/right/bottom/left.
    #[must_use]
    pub fn margins(&self) -> (LengthValue, LengthValue, LengthValue, LengthValue) {
        (
            self.margin_top,
            self.margin_right,
            self.margin_bottom,
            self.margin_left,
        )
    }

    /// Padding top/right/bottom/left.
    #[must_use]
    pub fn padding(&self) -> (LengthValue, LengthValue, LengthValue, LengthValue) {
        (
            self.padding_top,
            self.padding_right,
            self.padding_bottom,
            self.padding_left,
        )
    }

    /// Border-width top/right/bottom/left.
    #[must_use]
    pub fn border_widths(&self) -> (LengthValue, LengthValue, LengthValue, LengthValue) {
        (
            self.border_top_width,
            self.border_right_width,
            self.border_bottom_width,
            self.border_left_width,
        )
    }

    /// The text color.
    #[must_use]
    pub fn color(&self) -> Color {
        self.color
    }

    /// The background color.
    #[must_use]
    pub fn background_color(&self) -> Color {
        self.background_color
    }

    /// The font size.
    #[must_use]
    pub fn font_size(&self) -> LengthValue {
        self.font_size
    }

    pub(crate) fn with_display(self, display: Display) -> Self {
        Self { display, ..self }
    }
    pub(crate) fn with_width(self, width: LengthValue) -> Self {
        Self { width, ..self }
    }
    pub(crate) fn with_height(self, height: LengthValue) -> Self {
        Self { height, ..self }
    }
    pub(crate) fn with_margins(
        self,
        top: LengthValue,
        right: LengthValue,
        bottom: LengthValue,
        left: LengthValue,
    ) -> Self {
        Self {
            margin_top: top,
            margin_right: right,
            margin_bottom: bottom,
            margin_left: left,
            ..self
        }
    }
    pub(crate) fn with_padding(
        self,
        top: LengthValue,
        right: LengthValue,
        bottom: LengthValue,
        left: LengthValue,
    ) -> Self {
        Self {
            padding_top: top,
            padding_right: right,
            padding_bottom: bottom,
            padding_left: left,
            ..self
        }
    }
    pub(crate) fn with_border_widths(
        self,
        top: LengthValue,
        right: LengthValue,
        bottom: LengthValue,
        left: LengthValue,
    ) -> Self {
        Self {
            border_top_width: top,
            border_right_width: right,
            border_bottom_width: bottom,
            border_left_width: left,
            ..self
        }
    }
    pub(crate) fn with_color(self, color: Color) -> Self {
        Self { color, ..self }
    }
    pub(crate) fn with_background_color(self, background_color: Color) -> Self {
        Self {
            background_color,
            ..self
        }
    }
    pub(crate) fn with_font_size(self, font_size: LengthValue) -> Self {
        Self { font_size, ..self }
    }
}