formualizer_eval/engine/
sheet_registry.rs1use std::collections::HashMap;
2
3use crate::SheetId;
4
5#[derive(Default, Debug)]
6pub struct SheetRegistry {
7 id_by_name: HashMap<String, SheetId>,
8 name_by_id: Vec<String>,
9}
10
11impl SheetRegistry {
12 pub fn new() -> Self {
13 SheetRegistry::default()
14 }
15
16 pub fn id_for(&mut self, name: &str) -> SheetId {
17 if let Some(&id) = self.id_by_name.get(name) {
18 return id;
19 }
20
21 let id = self.name_by_id.len() as SheetId;
22 self.name_by_id.push(name.to_string());
23 self.id_by_name.insert(name.to_string(), id);
24 id
25 }
26
27 pub fn name(&self, id: SheetId) -> &str {
28 if (id as usize) < self.name_by_id.len() {
29 &self.name_by_id[id as usize]
30 } else {
31 ""
32 }
33 }
34
35 pub fn get_id(&self, name: &str) -> Option<SheetId> {
36 self.id_by_name.get(name).copied()
37 }
38
39 pub fn all_sheets(&self) -> Vec<(SheetId, String)> {
41 self.name_by_id
42 .iter()
43 .enumerate()
44 .filter(|(_, name)| !name.is_empty())
45 .map(|(id, name)| (id as SheetId, name.clone()))
46 .collect()
47 }
48
49 pub fn remove(&mut self, id: SheetId) -> Result<(), formualizer_common::ExcelError> {
52 use formualizer_common::{ExcelError, ExcelErrorKind};
53
54 if id as usize >= self.name_by_id.len() {
56 return Err(
57 ExcelError::new(ExcelErrorKind::Value).with_message("Sheet ID does not exist")
58 );
59 }
60
61 let name = self.name_by_id[id as usize].clone();
63 if name.is_empty() {
64 return Ok(());
66 }
67
68 self.id_by_name.remove(&name);
70
71 self.name_by_id[id as usize] = String::new();
73
74 Ok(())
75 }
76
77 pub fn rename(
79 &mut self,
80 id: SheetId,
81 new_name: &str,
82 ) -> Result<(), formualizer_common::ExcelError> {
83 use formualizer_common::{ExcelError, ExcelErrorKind};
84
85 if id as usize >= self.name_by_id.len() {
87 return Err(
88 ExcelError::new(ExcelErrorKind::Value).with_message("Sheet ID does not exist")
89 );
90 }
91
92 let old_name = self.name_by_id[id as usize].clone();
94
95 if let Some(&existing_id) = self.id_by_name.get(new_name) {
97 if existing_id != id {
98 return Err(ExcelError::new(ExcelErrorKind::Value)
99 .with_message(format!("Sheet name '{new_name}' already exists")));
100 }
101 }
102
103 self.id_by_name.remove(&old_name);
105
106 self.name_by_id[id as usize] = new_name.to_string();
108 self.id_by_name.insert(new_name.to_string(), id);
109
110 Ok(())
111 }
112}