1mod display;
2
3use crate::cell_options::{
4 BorderSide, BorderStyle, DataValidation, Fill, HorizontalAlign, NumberFormat, TextFormat,
5 TextWrap, VerticalAlign,
6};
7use crate::{ArcSourceCode, Cell, Result, Rgb, Scope};
8use csvp::Field;
9use std::collections;
10
11#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
12pub struct Row {
13 pub cells: Vec<Cell>,
14 pub border_color: Option<Rgb>,
15 pub border_style: BorderStyle,
16 pub borders: collections::HashSet<BorderSide>,
17 pub color: Option<Rgb>,
18 pub data_validation: Option<DataValidation>,
19 pub fill: Option<Fill>,
20 pub font_color: Option<Rgb>,
21 pub font_family: Option<String>,
22 pub font_size: Option<u8>,
23 pub horizontal_align: HorizontalAlign,
24 pub lock: bool,
25 pub note: Option<String>,
26 pub number_format: Option<NumberFormat>,
27 pub text_formats: collections::HashSet<TextFormat>,
28 pub text_wrap: TextWrap,
29 pub var: Option<String>,
30 pub vertical_align: VerticalAlign,
31}
32
33impl Row {
34 pub(crate) fn eval(
35 self,
36 source_code: &ArcSourceCode,
37 scope: &Scope,
38 row_a1: a1::Row,
39 ) -> Result<Self> {
40 let mut cells = Vec::with_capacity(self.cells.len());
41 for (cell_index, cell) in self.cells.into_iter().enumerate() {
42 let cell_a1 = a1::Address::new(cell_index, row_a1.y);
43 let ast = if let Some(a) = cell.ast {
44 Some(
45 a.eval(scope, Some(cell_a1))
46 .map_err(|e| source_code.eval_error(e, Some(cell_a1)))?,
47 )
48 } else {
49 None
50 };
51 cells.push(Cell { ast, ..cell });
52 }
53
54 Ok(Self { cells, ..self })
55 }
56
57 pub(crate) fn parse(record_result: &[Field], source_code: &ArcSourceCode) -> Result<Self> {
58 let mut row = Self::default();
59 Ok(Self {
60 cells: record_result
61 .iter()
62 .map(|field| Cell::parse(field, &mut row, source_code))
63 .collect::<Result<Vec<_>>>()?,
64 ..row
65 })
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use crate::test_utils::*;
73 use crate::*;
74
75 #[test]
76 fn eval_simple_ast() {
77 let mut cell = Cell::new(build_field("", (0, 0)));
78 cell.ast = Some(1.into());
79 assert!(Row {
80 cells: vec![cell],
81 ..Default::default()
82 }
83 .eval(&build_source_code(), &Scope::default(), 0.into())
84 .is_ok());
85 }
86
87 #[test]
88 fn parse() {
89 let row = Row::parse(
90 &vec![
91 build_field("a", (0, 0)),
92 build_field("b", (1, 0)),
93 build_field("c", (2, 0)),
94 ],
95 &build_source_code(),
96 )
97 .unwrap();
98
99 assert_eq!(row.cells.len(), 3);
100 }
101}