Skip to main content

formualizer_workbook/
worksheet.rs

1use std::sync::{Arc, RwLock};
2
3use crate::{RangeAddress, Workbook};
4use formualizer_common::LiteralValue;
5use std::collections::BTreeMap;
6
7/// A bindings-friendly worksheet handle backed by an Arc<RwLock<Workbook>>.
8/// For native Rust, prefer borrowing APIs on `Workbook` directly for better ergonomics.
9#[derive(Clone)]
10pub struct WorksheetHandle {
11    wb: Arc<RwLock<Workbook>>,
12    name: Arc<str>,
13}
14
15impl WorksheetHandle {
16    pub fn new(wb: Arc<RwLock<Workbook>>, name: impl Into<Arc<str>>) -> Self {
17        Self {
18            wb,
19            name: name.into(),
20        }
21    }
22
23    pub fn name(&self) -> &str {
24        &self.name
25    }
26
27    pub fn get_value(&self, row: u32, col: u32) -> Option<LiteralValue> {
28        self.wb
29            .read()
30            .ok()
31            .and_then(|w| w.get_value(&self.name, row, col))
32    }
33    pub fn get_formula(&self, row: u32, col: u32) -> Option<String> {
34        self.wb
35            .read()
36            .ok()
37            .and_then(|w| w.get_formula(&self.name, row, col))
38    }
39    pub fn set_value(&self, row: u32, col: u32, v: LiteralValue) -> Result<(), crate::IoError> {
40        self.wb
41            .write()
42            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
43            .set_value(&self.name, row, col, v)
44    }
45    pub fn set_formula(&self, row: u32, col: u32, f: &str) -> Result<(), crate::IoError> {
46        self.wb
47            .write()
48            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
49            .set_formula(&self.name, row, col, f)
50    }
51    pub fn set_values(
52        &self,
53        start_row: u32,
54        start_col: u32,
55        rows: &[Vec<LiteralValue>],
56    ) -> Result<(), crate::IoError> {
57        self.wb
58            .write()
59            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
60            .set_values(&self.name, start_row, start_col, rows)
61    }
62    pub fn set_formulas(
63        &self,
64        start_row: u32,
65        start_col: u32,
66        rows: &[Vec<String>],
67    ) -> Result<(), crate::IoError> {
68        self.wb
69            .write()
70            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
71            .set_formulas(&self.name, start_row, start_col, rows)
72    }
73    pub fn read_range(&self, addr: &RangeAddress) -> Vec<Vec<LiteralValue>> {
74        self.wb
75            .read()
76            .map(|w| w.read_range(addr))
77            .unwrap_or_default()
78    }
79    pub fn write_range(
80        &self,
81        cells: BTreeMap<(u32, u32), crate::traits::CellData>,
82    ) -> Result<(), crate::IoError> {
83        self.wb
84            .write()
85            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
86            .write_range(&self.name, (1, 1), cells)
87    }
88    pub fn evaluate_cell(&self, row: u32, col: u32) -> Result<LiteralValue, crate::IoError> {
89        self.wb
90            .write()
91            .map_err(|_| crate::IoError::Io(std::io::Error::other("lock")))?
92            .evaluate_cell(&self.name, row, col)
93    }
94}