visi_core/core/formula.rs
1use crate::core::RefType;
2use serde::{Deserialize, Serialize};
3
4/// Which part of an Excel Table a structured reference selects, as in
5/// `Sales[#Headers]`.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub enum SheetSection {
8 /// The body rows, excluding header and totals (default)
9 Data,
10 /// The header row.
11 Headers,
12 /// The totals row.
13 Totals,
14 /// Header, data and totals together.
15 All,
16}
17
18/// One piece of a compiled formula
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
20pub enum FormulaPart {
21 /// A literal stretch of the formula -- operators, function names,
22 /// constants -- copied through unchanged.
23 Text(String),
24 /// A single cell, as in `Sheet2!$A1`.
25 SheetReference {
26 /// Sheet the cell is on.
27 sheet_id: u64,
28 /// Row, 0-based.
29 row: usize,
30 /// Column, 0-based.
31 col: usize,
32 /// Whether the row was written with a `$`.
33 row_ref_type: RefType,
34 /// Whether the column was written with a `$`.
35 col_ref_type: RefType,
36 },
37 /// A whole column, held by column id so a column rename survives.
38 ColumnReference {
39 /// Sheet the column is on.
40 sheet_id: u64,
41 /// The column's identifier, not its position.
42 col_id: u64,
43 },
44 /// An Excel Table structured reference, as in `Sales[Amount]` or
45 /// `[@Amount]`.
46 StructuredReference {
47 /// Sheet the reference resolves against.
48 sheet_id: u64,
49 /// The referenced column, or `None` for a whole-table reference.
50 col_id: Option<u64>,
51 /// `true` for the `[@Amount]` form, which means the current row.
52 is_this_row: bool,
53 /// Which part of the table is selected.
54 section: SheetSection,
55 },
56 /// A rectangular range, as in `Sheet2!A1:$B$10`.
57 RangeReference {
58 /// Sheet the range is on.
59 sheet_id: u64,
60 /// First row, 0-based.
61 start_row: usize,
62 /// First column, 0-based.
63 start_col: usize,
64 /// Last row, 0-based and inclusive.
65 end_row: usize,
66 /// Last column, 0-based and inclusive.
67 end_col: usize,
68 /// Whether the start row was written with a `$`.
69 start_row_ref_type: RefType,
70 /// Whether the start column was written with a `$`.
71 start_col_ref_type: RefType,
72 /// Whether the end row was written with a `$`.
73 end_row_ref_type: RefType,
74 /// Whether the end column was written with a `$`.
75 end_col_ref_type: RefType,
76 },
77}
78
79/// A formula split into literal text and id-held references
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct CompiledFormula {
82 /// The pieces, in the order they appear in the formula text.
83 pub parts: Vec<FormulaPart>,
84}
85
86impl CompiledFormula {
87 /// Creates a plain formula from a raw string, without any parsed references.
88 pub fn plain(text: String) -> Self {
89 Self {
90 parts: vec![FormulaPart::Text(text)],
91 }
92 }
93}
94
95impl Default for CompiledFormula {
96 fn default() -> Self {
97 Self::plain(String::new())
98 }
99}