openprxl 0.1.0

A Rust spreadsheet library inspired by Python's openpyxl
Documentation
//! Cell and value types.

use crate::style::StyleId;

/// A value that can be stored in a worksheet cell.
#[derive(Debug, Clone, Default, PartialEq)]
pub enum Value {
    /// An empty cell.
    #[default]
    Empty,
    /// A numeric value.
    Number(f64),
    /// A string value.
    String(String),
    /// A boolean value.
    Bool(bool),
    /// A formula string, including the leading `=`.
    Formula(String),
    /// An Excel error value such as `#DIV/0!` or `#VALUE!`.
    Error(String),
    /// A date/time value stored as an Excel serial date.
    ///
    /// When saved, this is written as a number with the standard date
    /// number format unless the cell has an explicit style.
    Date(f64),
}

impl Value {
    /// Returns `true` if the value is empty.
    pub fn is_empty(&self) -> bool {
        matches!(self, Value::Empty)
    }

    /// Returns `true` if the value is a formula.
    pub fn is_formula(&self) -> bool {
        matches!(self, Value::Formula(_))
    }

    /// If this value is a formula, return the formula text (with `=`).
    pub fn as_formula(&self) -> Option<&str> {
        match self {
            Value::Formula(f) => Some(f),
            _ => None,
        }
    }

    /// If this value is a number, return it.
    pub fn as_number(&self) -> Option<f64> {
        match self {
            Value::Number(n) => Some(*n),
            _ => None,
        }
    }

    /// If this value is a string, return it.
    pub fn as_string(&self) -> Option<&str> {
        match self {
            Value::String(s) => Some(s),
            _ => None,
        }
    }
}

impl From<&str> for Value {
    fn from(s: &str) -> Self {
        Value::String(s.to_string())
    }
}

impl From<String> for Value {
    fn from(s: String) -> Self {
        Value::String(s)
    }
}

impl From<f64> for Value {
    fn from(n: f64) -> Self {
        Value::Number(n)
    }
}

impl From<i32> for Value {
    fn from(n: i32) -> Self {
        Value::Number(f64::from(n))
    }
}

impl From<i64> for Value {
    fn from(n: i64) -> Self {
        Value::Number(n as f64)
    }
}

impl From<bool> for Value {
    fn from(b: bool) -> Self {
        Value::Bool(b)
    }
}

/// A single worksheet cell.
#[derive(Debug, Clone, PartialEq)]
pub struct Cell {
    pub(crate) value: Value,
    pub(crate) style_id: Option<StyleId>,
}

impl Cell {
    /// Create a new empty cell.
    pub const fn empty() -> Self {
        Self {
            value: Value::Empty,
            style_id: None,
        }
    }

    /// Create a new cell with a value.
    pub fn new<V: Into<Value>>(value: V) -> Self {
        Self {
            value: value.into(),
            style_id: None,
        }
    }

    /// Get the cell value.
    pub fn value(&self) -> &Value {
        &self.value
    }

    /// Set the cell value.
    pub fn set_value<V: Into<Value>>(&mut self, value: V) {
        self.value = value.into();
    }

    /// Set the cell to a formula string.
    ///
    /// The string should begin with `=`.
    pub fn set_formula<S: Into<String>>(&mut self, formula: S) {
        self.value = Value::Formula(formula.into());
    }

    /// Get the style id, if any.
    pub fn style_id(&self) -> Option<StyleId> {
        self.style_id
    }

    /// Set the style id.
    pub fn set_style_id(&mut self, style_id: StyleId) {
        self.style_id = Some(style_id);
    }

    /// Clear the style.
    pub fn clear_style(&mut self) {
        self.style_id = None;
    }
}

impl Default for Cell {
    fn default() -> Self {
        Cell::empty()
    }
}

impl<V: Into<Value>> From<V> for Cell {
    fn from(value: V) -> Self {
        Cell::new(value)
    }
}