openprxl 0.1.0

A Rust spreadsheet library inspired by Python's openpyxl
Documentation
//! Border styling.

/// A complete cell border.
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub struct Border {
    pub left: Option<Side>,
    pub right: Option<Side>,
    pub top: Option<Side>,
    pub bottom: Option<Side>,
    pub diagonal: Option<DiagonalBorder>,
}

impl Border {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn left(mut self, side: Side) -> Self {
        self.left = Some(side);
        self
    }

    pub fn right(mut self, side: Side) -> Self {
        self.right = Some(side);
        self
    }

    pub fn top(mut self, side: Side) -> Self {
        self.top = Some(side);
        self
    }

    pub fn bottom(mut self, side: Side) -> Self {
        self.bottom = Some(side);
        self
    }

    pub fn diagonal(mut self, diagonal: DiagonalBorder) -> Self {
        self.diagonal = Some(diagonal);
        self
    }

    /// Create a thin border on all four sides.
    pub fn thin_all() -> Self {
        let side = Side::thin();
        Self {
            left: Some(side.clone()),
            right: Some(side.clone()),
            top: Some(side.clone()),
            bottom: Some(side.clone()),
            diagonal: None,
        }
    }

    /// Create a medium border on all four sides.
    pub fn medium_all() -> Self {
        let side = Side::medium();
        Self {
            left: Some(side.clone()),
            right: Some(side.clone()),
            top: Some(side.clone()),
            bottom: Some(side.clone()),
            diagonal: None,
        }
    }
}

/// A single border side.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Side {
    pub style: BorderStyle,
    pub color: Option<String>,
}

impl Side {
    pub fn new(style: BorderStyle) -> Self {
        Self {
            style,
            color: None,
        }
    }

    pub fn thin() -> Self {
        Self::new(BorderStyle::Thin)
    }

    pub fn medium() -> Self {
        Self::new(BorderStyle::Medium)
    }

    pub fn thick() -> Self {
        Self::new(BorderStyle::Thick)
    }

    pub fn color<S: Into<String>>(mut self, color: S) -> Self {
        self.color = Some(color.into());
        self
    }
}

/// Border line styles.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub enum BorderStyle {
    #[default]
    None,
    Thin,
    Medium,
    Thick,
    Dashed,
    Dotted,
    Double,
}

impl std::fmt::Display for BorderStyle {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            BorderStyle::None => write!(f, "none"),
            BorderStyle::Thin => write!(f, "thin"),
            BorderStyle::Medium => write!(f, "medium"),
            BorderStyle::Thick => write!(f, "thick"),
            BorderStyle::Dashed => write!(f, "dashed"),
            BorderStyle::Dotted => write!(f, "dotted"),
            BorderStyle::Double => write!(f, "double"),
        }
    }
}

/// Diagonal border settings.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DiagonalBorder {
    pub style: BorderStyle,
    pub color: Option<String>,
    pub up: bool,
    pub down: bool,
}

impl DiagonalBorder {
    pub fn new(style: BorderStyle) -> Self {
        Self {
            style,
            color: None,
            up: false,
            down: false,
        }
    }

    pub fn up(mut self) -> Self {
        self.up = true;
        self
    }

    pub fn down(mut self) -> Self {
        self.down = true;
        self
    }

    pub fn color<S: Into<String>>(mut self, color: S) -> Self {
        self.color = Some(color.into());
        self
    }
}