use serde::{Deserialize, Deserializer, Serialize};
use crate::error::WorkbookError;
use crate::value::Value;
#[derive(Debug, Clone, PartialEq, Hash, Serialize, Deserialize)]
#[serde(try_from = "CellDe")]
pub struct Cell {
#[serde(skip_serializing_if = "Option::is_none")]
formula: Option<String>,
value: Value,
}
impl Cell {
pub fn literal(value: Value) -> Result<Self, WorkbookError> {
if matches!(value, Value::Empty) {
return Err(WorkbookError::EmptyLiteral);
}
Ok(Self {
formula: None,
value,
})
}
pub fn with_formula(formula: impl Into<String>, value: Value) -> Self {
Self {
formula: Some(formula.into()),
value,
}
}
pub fn value(&self) -> &Value {
&self.value
}
pub fn formula(&self) -> Option<&str> {
self.formula.as_deref()
}
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct CellDe {
#[serde(default, deserialize_with = "de_formula")]
formula: Option<String>,
value: Value,
}
fn de_formula<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<String>, D::Error> {
String::deserialize(deserializer).map(Some)
}
impl TryFrom<CellDe> for Cell {
type Error = WorkbookError;
fn try_from(de: CellDe) -> Result<Self, Self::Error> {
if de.formula.is_none() && matches!(de.value, Value::Empty) {
return Err(WorkbookError::EmptyLiteral);
}
Ok(Self {
formula: de.formula,
value: de.value,
})
}
}