ravenrs_sheet/model/
cell.rs1use std::sync::Arc;
4
5use crate::base::{RangeRef, Value};
6use crate::formula::Expr;
7use serde::{Deserialize, Serialize};
8
9use crate::model::python::PyCode;
10use crate::model::style::StyleId;
11
12#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
14pub struct Formula {
15 pub text: String,
16 #[serde(skip)]
17 pub expr: Option<Arc<Expr>>,
18 pub array: Option<RangeRef>,
21 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
26 pub dynamic: bool,
27}
28
29impl Formula {
30 pub fn new(text: &str) -> Formula {
33 let body = text.strip_prefix('=').unwrap_or(text);
34 match crate::formula::parse(body) {
35 Ok(e) => Formula { text: crate::formula::print(&e), expr: Some(Arc::new(e)), array: None, dynamic: false },
36 Err(_) => Formula { text: body.to_string(), expr: None, array: None, dynamic: false },
37 }
38 }
39 pub fn from_expr(e: Expr) -> Formula {
40 Formula { text: crate::formula::print(&e), expr: Some(Arc::new(e)), array: None, dynamic: false }
41 }
42 pub fn expr(&self) -> Option<Expr> {
44 self.expr.as_deref().cloned().or_else(|| crate::formula::parse(&self.text).ok())
45 }
46 pub fn expr_arc(&self) -> Option<Arc<Expr>> {
48 self.expr.clone().or_else(|| crate::formula::parse(&self.text).ok().map(Arc::new))
49 }
50 pub fn with_expr<R>(&self, f: impl FnOnce(&Expr) -> R) -> Option<R> {
55 match &self.expr {
56 Some(e) => Some(f(e)),
57 None => crate::formula::parse(&self.text).ok().map(|e| f(&e)),
58 }
59 }
60}
61
62#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
64pub struct CellPicture {
65 #[serde(with = "crate::model::b64")]
67 pub data: Vec<u8>,
68 pub mime: String,
69 pub alt: String,
70}
71
72#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
73pub struct Cell {
74 pub value: Value,
76 pub formula: Option<Arc<Formula>>,
77 pub style: StyleId,
78 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub py: Option<Arc<PyCode>>,
81}
82
83impl Cell {
84 pub fn value(v: Value) -> Cell {
85 Cell { value: v, formula: None, style: StyleId::DEFAULT, py: None }
86 }
87 pub fn formula(f: Formula) -> Cell {
88 Cell { value: Value::Empty, formula: Some(Arc::new(f)), style: StyleId::DEFAULT, py: None }
89 }
90 pub fn styled(v: Value, style: StyleId) -> Cell {
92 Cell { value: v, formula: None, style, py: None }
93 }
94 pub fn is_blank(&self) -> bool {
96 self.value.is_empty() && self.formula.is_none() && self.style == StyleId::DEFAULT && self.py.is_none()
97 }
98 pub fn has_content(&self) -> bool {
100 !self.value.is_empty() || self.formula.is_some() || self.py.is_some()
101 }
102 pub fn clear_content(&mut self) {
104 self.value = Value::Empty;
105 self.formula = None;
106 self.py = None;
107 }
108 pub fn input_text(&self) -> String {
110 if let Some(py) = &self.py {
111 return py.code.clone();
112 }
113 if let Some(f) = &self.formula {
114 return format!("={}", f.text);
115 }
116 match &self.value {
117 Value::Text(t) => {
118 t.to_string()
121 }
122 v => v.display(),
123 }
124 }
125 pub fn bar_text(&self) -> String {
128 match &self.formula {
129 Some(f) if f.array.is_some() => format!("{{={}}}", f.text),
130 _ => self.input_text(),
131 }
132 }
133}