diff --git a/src/book/mod.rs b/src/book/mod.rs index a8b04a1..53bd0c1 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -78,6 +78,11 @@ impl Book { Ok(&self.get_sheet()?.name) } + pub fn set_sheet_name(&mut self, idx: usize, sheet_name: &str) -> Result<()> { + self.get_sheet_by_idx_mut(idx)?.set_name(sheet_name); + Ok(()) + } + /// Get the sheet data for the current worksheet. pub fn get_sheet_data(&self) -> Result<&SheetData> { Ok(&self.get_sheet()?.sheet_data) @@ -251,6 +256,14 @@ impl Book { .worksheet_mut(self.current_sheet) .map_err(|s| anyhow!("Invalid Worksheet: {}", s))?) } + + pub(crate) fn get_sheet_by_idx_mut(&mut self, idx: usize) -> Result<&mut Worksheet> { + Ok(self + .model + .workbook + .worksheet_mut(idx as u32) + .map_err(|s| anyhow!("Invalid Worksheet: {}", s))?) + } } impl Default for Book { diff --git a/src/ui/cmd.rs b/src/ui/cmd.rs index 1700ebc..fd0ba06 100644 --- a/src/ui/cmd.rs +++ b/src/ui/cmd.rs @@ -7,6 +7,7 @@ pub enum Cmd<'a> { Write(Option<&'a str>), InsertRow(usize), InsertColumns(usize), + RenameSheet(Option, &'a str), Edit(&'a str), Help(Option<&'a str>), Quit, @@ -39,6 +40,9 @@ pub fn parse<'cmd, 'i: 'cmd>(input: &'i str) -> Result>, &'stat if let Some(cmd) = try_consume_quit(cursor.clone())? { return Ok(Some(cmd)); } + if let Some(cmd) = try_consume_rename_sheet(cursor.clone())? { + return Ok(Some(cmd)); + } Ok(None) } @@ -209,3 +213,37 @@ fn try_consume_quit<'cmd, 'i: 'cmd>( } return Ok(Some(Cmd::Quit)); } + +fn try_consume_rename_sheet<'cmd, 'i: 'cmd>( + mut input: StrCursor<'i>, +) -> Result>, &'static str> { + const LONG: &'static str = "rename-sheet"; + if compare(input.clone(), LONG) { + input.seek(LONG.len()); + } else { + return Ok(None); + } + if input.remaining() > 0 && !is_ws(&mut input) { + return Err("Invalid command: Did you mean to type `rename-sheet [idx] `?"); + } + let (idx, rest) = try_consume_usize(input.clone()); + let arg = rest.span(0..).trim(); + if arg.is_empty() { + return Err("Invalid command: `rename-sheet` requires a sheet name argument?"); + } + return Ok(Some(Cmd::RenameSheet(idx, arg))); +} + +fn try_consume_usize<'cmd, 'i: 'cmd>( + mut input: StrCursor<'i>, +) -> (Option, StrCursor<'i>) { + let mut out = String::new(); + let original_input = input.clone(); + while input.peek_next().map(|c| (*c as char).is_ascii_digit()).unwrap_or(false) { + out.push(*input.next().unwrap() as char); + } + if out.len() > 0 { + return (Some(out.parse().unwrap()), input.clone()); + } + (None, original_input) +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 78f1fe5..425d70e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -278,6 +278,17 @@ impl<'ws> Workspace<'ws> { self.book.evaluate(); Ok(true) } + Ok(Some(Cmd::RenameSheet(idx, name))) => { + match idx { + Some(idx) => { + self.book.set_sheet_name(idx, name)?; + } + _ => { + self.book.set_sheet_name(self.book.current_sheet as usize, name)?; + } + } + Ok(true) + } Ok(Some(Cmd::Quit)) => { // TODO(zaphar): We probably need to do better than this std::process::exit(0);