From 9f7b4bba8e63492cdd77b85e6391f76974d2ec73 Mon Sep 17 00:00:00 2001 From: nibon7 Date: Tue, 9 Jan 2024 22:44:00 +0800 Subject: [PATCH] Return error when creating `FileBackedHistory` with invalid capacity --- examples/demo.rs | 4 ++-- src/history/file_backed.rs | 33 ++++++++++++++++++++++----------- src/result.rs | 6 ++++++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/examples/demo.rs b/examples/demo.rs index 2e7a402e..780599f1 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -10,7 +10,7 @@ use { default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings, ColumnarMenu, DefaultCompleter, DefaultHinter, DefaultPrompt, DefaultValidator, EditCommand, EditMode, Emacs, ExampleHighlighter, Keybindings, ListMenu, Reedline, - ReedlineEvent, ReedlineMenu, Signal, Vi, + ReedlineEvent, ReedlineMenu, Result, Signal, Vi, }, }; @@ -18,7 +18,7 @@ use reedline::CursorConfig; #[cfg(not(any(feature = "sqlite", feature = "sqlite-dynlib")))] use reedline::FileBackedHistory; -fn main() -> std::io::Result<()> { +fn main() -> Result<()> { println!("Ctrl-D to quit"); // quick command like parameter handling let vi_mode = matches!(std::env::args().nth(1), Some(x) if x == "--vi"); diff --git a/src/history/file_backed.rs b/src/history/file_backed.rs index 28b437f7..9923d7cb 100644 --- a/src/history/file_backed.rs +++ b/src/history/file_backed.rs @@ -37,8 +37,15 @@ impl Default for FileBackedHistory { /// Creates an in-memory [`History`] with a maximal capacity of [`HISTORY_SIZE`]. /// /// To create a [`History`] that is synchronized with a file use [`FileBackedHistory::with_file()`] + /// + /// # Panics + /// + /// If `HISTORY_SIZE == 0` or `HISTORY_SIZE == usize::MAX` fn default() -> Self { - Self::new(HISTORY_SIZE) + match Self::new(HISTORY_SIZE) { + Ok(history) => history, + Err(e) => panic!("{}", e), + } } } @@ -283,20 +290,24 @@ impl History for FileBackedHistory { impl FileBackedHistory { /// Creates a new in-memory history that remembers `n <= capacity` elements /// - /// # Panics - /// - /// If `capacity == usize::MAX` - pub fn new(capacity: usize) -> Self { - if capacity == usize::MAX { - panic!("History capacity too large to be addressed safely"); + pub fn new(capacity: usize) -> Result { + if capacity == 0 { + return Err(ReedlineError(ReedlineErrorVariants::OtherHistoryError( + "History capacity too small to be addressed safely", + ))); + } else if capacity == usize::MAX { + return Err(ReedlineError(ReedlineErrorVariants::OtherHistoryError( + "History capacity too large to be addressed safely", + ))); } - FileBackedHistory { + + Ok(FileBackedHistory { capacity, entries: VecDeque::new(), file: None, len_on_disk: 0, session: None, - } + }) } /// Creates a new history with an associated history file. @@ -307,8 +318,8 @@ impl FileBackedHistory { /// /// **Side effects:** creates all nested directories to the file /// - pub fn with_file(capacity: usize, file: PathBuf) -> std::io::Result { - let mut hist = Self::new(capacity); + pub fn with_file(capacity: usize, file: PathBuf) -> Result { + let mut hist = Self::new(capacity)?; if let Some(base_dir) = file.parent() { std::fs::create_dir_all(base_dir)?; } diff --git a/src/result.rs b/src/result.rs index a0691472..8766a3bb 100644 --- a/src/result.rs +++ b/src/result.rs @@ -23,6 +23,12 @@ pub enum ReedlineErrorVariants { #[derive(Debug)] pub struct ReedlineError(pub ReedlineErrorVariants); +impl From for ReedlineError { + fn from(err: std::io::Error) -> Self { + Self(ReedlineErrorVariants::IOError(err)) + } +} + impl Display for ReedlineError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f)