use crate::draw::{Annotation, DrawFrame};
use crate::validation::ValidationRef;
use crate::value_::Value;
use crate::CellStyleRef;
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone, Copy)]
pub struct CellSpan {
pub(crate) row_span: u32,
pub(crate) col_span: u32,
}
impl Default for CellSpan {
fn default() -> Self {
Self {
row_span: 1,
col_span: 1,
}
}
}
impl Display for CellSpan {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "(+{}+{})", self.row_span, self.col_span)
}
}
impl From<CellSpan> for (u32, u32) {
fn from(span: CellSpan) -> Self {
(span.row_span, span.col_span)
}
}
impl From<&CellSpan> for (u32, u32) {
fn from(span: &CellSpan) -> Self {
(span.row_span, span.col_span)
}
}
impl CellSpan {
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.row_span == 1 && self.col_span == 1
}
#[inline]
pub fn set_row_span(&mut self, rows: u32) {
assert!(rows > 0);
self.row_span = rows;
}
#[inline]
pub fn row_span(&self) -> u32 {
self.row_span
}
#[inline]
pub fn set_col_span(&mut self, cols: u32) {
assert!(cols > 0);
self.col_span = cols;
}
#[inline]
pub fn col_span(&self) -> u32 {
self.col_span
}
}
#[derive(Debug, Clone)]
pub(crate) struct CellData {
pub(crate) value: Value,
pub(crate) formula: Option<String>,
pub(crate) style: Option<String>,
pub(crate) repeat: u32,
pub(crate) extra: Option<Box<CellDataExt>>,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct CellDataExt {
pub(crate) validation_name: Option<String>,
pub(crate) span: CellSpan,
pub(crate) matrix_span: CellSpan,
pub(crate) annotation: Option<Annotation>,
pub(crate) draw_frames: Vec<DrawFrame>,
}
impl Default for CellData {
#[inline]
fn default() -> Self {
Self {
value: Default::default(),
formula: None,
style: None,
repeat: 1,
extra: None,
}
}
}
impl CellData {
pub(crate) fn is_empty(&self) -> bool {
self.value == Value::Empty && self.formula.is_none()
}
pub(crate) fn is_void(&self) -> bool {
self.value == Value::Empty
&& self.formula.is_none()
&& self.style.is_none()
&& (self.extra.is_none()
|| self.extra.as_ref().is_some_and(|v| {
v.validation_name.is_none()
&& v.span.is_empty()
&& v.matrix_span.is_empty()
&& v.annotation.is_none()
&& v.draw_frames.is_empty()
}))
}
pub(crate) fn extra_mut(&mut self) -> &mut CellDataExt {
if self.extra.is_none() {
self.extra = Some(Box::default());
}
self.extra.as_mut().expect("celldataext")
}
pub(crate) fn cloned_cell_content(&self) -> CellContent {
let (validation_name, span, matrix_span, annotation, draw_frames) =
if let Some(extra) = &self.extra {
(
extra.validation_name.clone(),
extra.span,
extra.matrix_span,
extra.annotation.clone(),
extra.draw_frames.clone(),
)
} else {
(
None,
Default::default(),
Default::default(),
None,
Vec::new(),
)
};
CellContent {
value: self.value.clone(),
style: self.style.clone(),
formula: self.formula.clone(),
repeat: self.repeat,
validation_name,
span,
matrix_span,
annotation,
draw_frames,
}
}
pub(crate) fn into_cell_content(self) -> CellContent {
let (validation_name, span, matrix_span, annotation, draw_frames) =
if let Some(extra) = self.extra {
(
extra.validation_name,
extra.span,
extra.matrix_span,
extra.annotation,
extra.draw_frames,
)
} else {
(
None,
Default::default(),
Default::default(),
None,
Vec::new(),
)
};
CellContent {
value: self.value,
style: self.style,
formula: self.formula,
repeat: self.repeat,
validation_name,
span,
matrix_span,
annotation,
draw_frames,
}
}
pub(crate) fn cell_content_ref(&self) -> CellContentRef<'_> {
let (validation_name, span, matrix_span, annotation, draw_frames) =
if let Some(extra) = &self.extra {
(
extra.validation_name.as_ref(),
Some(&extra.span),
Some(&extra.matrix_span),
extra.annotation.as_ref(),
Some(&extra.draw_frames),
)
} else {
(None, None, None, None, None)
};
CellContentRef {
value: &self.value,
style: self.style.as_ref(),
formula: self.formula.as_ref(),
repeat: &self.repeat,
validation_name,
span,
matrix_span,
annotation,
draw_frames,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct CellContentRef<'a> {
pub value: &'a Value,
pub style: Option<&'a String>,
pub formula: Option<&'a String>,
pub repeat: &'a u32,
pub validation_name: Option<&'a String>,
pub span: Option<&'a CellSpan>,
pub matrix_span: Option<&'a CellSpan>,
pub annotation: Option<&'a Annotation>,
pub draw_frames: Option<&'a Vec<DrawFrame>>,
}
impl<'a> CellContentRef<'a> {
#[inline]
pub fn value(&self) -> &'a Value {
self.value
}
#[inline]
pub fn formula(&self) -> Option<&'a String> {
self.formula
}
#[inline]
pub fn style(&self) -> Option<&'a String> {
self.style
}
#[inline]
pub fn repeat(&self) -> &'a u32 {
self.repeat
}
#[inline]
pub fn validation(&self) -> Option<&'a String> {
self.validation_name
}
#[inline]
pub fn row_span(&self) -> u32 {
if let Some(span) = self.span {
span.row_span
} else {
1
}
}
#[inline]
pub fn col_span(&self) -> u32 {
if let Some(span) = self.span {
span.col_span
} else {
1
}
}
#[inline]
pub fn matrix_row_span(&self) -> u32 {
if let Some(matrix_span) = self.matrix_span {
matrix_span.row_span
} else {
1
}
}
#[inline]
pub fn matrix_col_span(&self) -> u32 {
if let Some(matrix_span) = self.matrix_span {
matrix_span.col_span
} else {
1
}
}
#[inline]
pub fn annotation(&self) -> Option<&'a Annotation> {
self.annotation
}
#[inline]
pub fn draw_frames(&self) -> Option<&'a Vec<DrawFrame>> {
self.draw_frames
}
}
#[derive(Debug, Clone, Default)]
pub struct CellContent {
pub value: Value,
pub style: Option<String>,
pub formula: Option<String>,
pub repeat: u32,
pub validation_name: Option<String>,
pub span: CellSpan,
pub matrix_span: CellSpan,
pub annotation: Option<Annotation>,
pub draw_frames: Vec<DrawFrame>,
}
impl CellContent {
#[inline]
pub fn new() -> Self {
Default::default()
}
pub(crate) fn into_celldata(mut self) -> CellData {
let extra = self.into_celldata_ext();
CellData {
value: self.value,
formula: self.formula,
style: self.style,
repeat: self.repeat,
extra,
}
}
#[allow(clippy::wrong_self_convention)]
pub(crate) fn into_celldata_ext(&mut self) -> Option<Box<CellDataExt>> {
if self.validation_name.is_some()
|| !self.span.is_empty()
|| !self.matrix_span.is_empty()
|| self.annotation.is_some()
|| !self.draw_frames.is_empty()
{
Some(Box::new(CellDataExt {
validation_name: self.validation_name.take(),
span: self.span,
matrix_span: self.matrix_span,
annotation: self.annotation.take(),
draw_frames: std::mem::take(&mut self.draw_frames),
}))
} else {
None
}
}
#[inline]
pub fn value(&self) -> &Value {
&self.value
}
#[inline]
pub fn set_value<V: Into<Value>>(&mut self, value: V) {
self.value = value.into();
}
#[inline]
pub fn formula(&self) -> Option<&String> {
self.formula.as_ref()
}
#[inline]
pub fn set_formula<V: Into<String>>(&mut self, formula: V) {
self.formula = Some(formula.into());
}
#[inline]
pub fn clear_formula(&mut self) {
self.formula = None;
}
#[inline]
pub fn style(&self) -> Option<&String> {
self.style.as_ref()
}
#[inline]
pub fn set_style(&mut self, style: &CellStyleRef) {
self.style = Some(style.to_string());
}
#[inline]
pub fn clear_style(&mut self) {
self.style = None;
}
#[inline]
pub fn set_repeat(&mut self, repeat: u32) {
assert!(repeat > 0);
self.repeat = repeat;
}
#[inline]
pub fn get_repeat(&mut self) -> u32 {
self.repeat
}
#[inline]
pub fn validation(&self) -> Option<&String> {
self.validation_name.as_ref()
}
#[inline]
pub fn set_validation(&mut self, validation: &ValidationRef) {
self.validation_name = Some(validation.to_string());
}
#[inline]
pub fn clear_validation(&mut self) {
self.validation_name = None;
}
#[inline]
pub fn set_row_span(&mut self, rows: u32) {
assert!(rows > 0);
self.span.row_span = rows;
}
#[inline]
pub fn row_span(&self) -> u32 {
self.span.row_span
}
#[inline]
pub fn set_col_span(&mut self, cols: u32) {
assert!(cols > 0);
self.span.col_span = cols;
}
#[inline]
pub fn col_span(&self) -> u32 {
self.span.col_span
}
#[inline]
pub fn set_matrix_row_span(&mut self, rows: u32) {
assert!(rows > 0);
self.matrix_span.row_span = rows;
}
#[inline]
pub fn matrix_row_span(&self) -> u32 {
self.matrix_span.row_span
}
#[inline]
pub fn set_matrix_col_span(&mut self, cols: u32) {
assert!(cols > 0);
self.matrix_span.col_span = cols;
}
#[inline]
pub fn matrix_col_span(&self) -> u32 {
self.matrix_span.col_span
}
#[inline]
pub fn set_annotation(&mut self, annotation: Annotation) {
self.annotation = Some(annotation);
}
#[inline]
pub fn clear_annotation(&mut self) {
self.annotation = None;
}
#[inline]
pub fn annotation(&self) -> Option<&Annotation> {
self.annotation.as_ref()
}
#[inline]
pub fn set_draw_frames(&mut self, draw_frames: Vec<DrawFrame>) {
self.draw_frames = draw_frames;
}
#[inline]
pub fn draw_frames(&self) -> &Vec<DrawFrame> {
&self.draw_frames
}
}