From c6dbcc6017a7a1b343a585729239ad52ccb6ceba Mon Sep 17 00:00:00 2001 From: Tim Oram Date: Thu, 17 Sep 2020 10:45:49 -0230 Subject: Move error handling to process module The error handling module needed to have state provided to it from other modules, which meant that the other modules needed to understand how the error module worked. This was awkward and fragile. This moves the error handling code into the process module and makes it a global system. This has the advantage of not requiring tracking of the previous state and allows for the removal of the HandleInputResult struct. --- src/confirm_abort/mod.rs | 8 +- src/confirm_rebase/mod.rs | 8 +- src/edit/mod.rs | 8 +- src/error/mod.rs | 75 ---------------- src/external_editor/mod.rs | 35 ++++---- src/list/mod.rs | 15 ++-- src/main.rs | 1 - src/process/error.rs | 29 +++++++ src/process/handle_input_result.rs | 52 ------------ src/process/help.rs | 8 +- src/process/mod.rs | 169 ++++++++++++++++++------------------- src/process/process_module.rs | 5 +- src/process/process_result.rs | 41 +++------ src/process/state.rs | 1 - src/process/testutil.rs | 8 +- src/show_commit/mod.rs | 17 ++-- src/window_size_error/mod.rs | 6 +- 17 files changed, 183 insertions(+), 303 deletions(-) delete mode 100644 src/error/mod.rs create mode 100644 src/process/error.rs delete mode 100644 src/process/handle_input_result.rs diff --git a/src/confirm_abort/mod.rs b/src/confirm_abort/mod.rs index 3fb8351..8813cd0 100644 --- a/src/confirm_abort/mod.rs +++ b/src/confirm_abort/mod.rs @@ -2,8 +2,8 @@ use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; use crate::process::exit_status::ExitStatus; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::view_data::ViewData; use crate::view::View; @@ -25,10 +25,10 @@ impl ProcessModule for ConfirmAbort { input_handler: &InputHandler<'_>, git_interactive: &mut GitInteractive, _view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { let input = input_handler.get_input(InputMode::Confirm); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); match input { Input::Yes => { git_interactive.clear(); @@ -39,7 +39,7 @@ impl ProcessModule for ConfirmAbort { }, _ => {}, } - result.build() + result } } diff --git a/src/confirm_rebase/mod.rs b/src/confirm_rebase/mod.rs index 717f25d..b400fc9 100644 --- a/src/confirm_rebase/mod.rs +++ b/src/confirm_rebase/mod.rs @@ -2,8 +2,8 @@ use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; use crate::process::exit_status::ExitStatus; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::view_data::ViewData; use crate::view::View; @@ -25,10 +25,10 @@ impl ProcessModule for ConfirmRebase { input_handler: &InputHandler<'_>, _git_interactive: &mut GitInteractive, _view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { let input = input_handler.get_input(InputMode::Confirm); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); match input { Input::Yes => { result = result.exit_status(ExitStatus::Good).state(State::Exiting); @@ -38,7 +38,7 @@ impl ProcessModule for ConfirmRebase { }, _ => {}, } - result.build() + result } } diff --git a/src/edit/mod.rs b/src/edit/mod.rs index 9ac45c6..9b28fc3 100644 --- a/src/edit/mod.rs +++ b/src/edit/mod.rs @@ -2,8 +2,8 @@ use crate::display::display_color::DisplayColor; use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::line_segment::LineSegment; use crate::view::view_data::ViewData; @@ -72,11 +72,11 @@ impl ProcessModule for Edit { input_handler: &InputHandler<'_>, git_interactive: &mut GitInteractive, view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { let result = loop { let input = input_handler.get_input(InputMode::Raw); - let result = HandleInputResultBuilder::new(input); + let result = ProcessResult::new().input(input); match input { Input::Character(c) => { let start = UnicodeSegmentation::graphemes(self.content.as_str(), true) @@ -137,7 +137,7 @@ impl ProcessModule for Edit { } break result; }; - result.build() + result } } diff --git a/src/error/mod.rs b/src/error/mod.rs deleted file mode 100644 index 0cab480..0000000 --- a/src/error/mod.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::git_interactive::GitInteractive; -use crate::input::input_handler::{InputHandler, InputMode}; -use crate::input::Input; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; -use crate::process::process_module::ProcessModule; -use crate::process::state::State; -use crate::view::view_data::ViewData; -use crate::view::View; - -pub struct Error { - return_state: State, - view_data: Option, - view_data_no_error: ViewData, -} - -impl ProcessModule for Error { - fn activate(&mut self, state: &State, _git_interactive: &GitInteractive) { - if let State::Error { - ref message, - ref return_state, - } = *state - { - self.view_data = Some(ViewData::new_error(message.as_str())); - self.return_state = *return_state.clone(); - } - else { - self.view_data = None; - } - } - - fn deactivate(&mut self) { - self.view_data = None; - } - - fn build_view_data(&mut self, view: &View<'_>, _: &GitInteractive) -> &ViewData { - let (view_width, view_height) = view.get_view_size(); - if let Some(ref mut view_data) = self.view_data { - view_data.set_view_size(view_width, view_height); - view_data.rebuild(); - view_data - } - else { - self.view_data_no_error.set_view_size(view_width, view_height); - self.view_data_no_error.rebuild(); - &self.view_data_no_error - } - } - - fn handle_input( - &mut self, - input_handler: &InputHandler<'_>, - _git_interactive: &mut GitInteractive, - _view: &View<'_>, - ) -> HandleInputResult - { - let input = input_handler.get_input(InputMode::Default); - let mut result = HandleInputResultBuilder::new(input); - if let Input::Resize = input { - } - else { - result = result.state(self.return_state.clone()); - } - result.build() - } -} - -impl Error { - pub(crate) fn new() -> Self { - Self { - return_state: State::List, - view_data: None, - view_data_no_error: ViewData::new_error("Help module activated without error message"), - } - } -} diff --git a/src/external_editor/mod.rs b/src/external_editor/mod.rs index e1f87eb..e53d13a 100644 --- a/src/external_editor/mod.rs +++ b/src/external_editor/mod.rs @@ -6,9 +6,8 @@ use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; use crate::process::exit_status::ExitStatus; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; -use crate::process::process_result::{ProcessResult, ProcessResultBuilder}; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::view_data::ViewData; use crate::view::View; @@ -67,12 +66,12 @@ impl<'e> ProcessModule for ExternalEditor<'e> { input_handler: &InputHandler<'_>, _git_interactive: &mut GitInteractive, _view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { match self.state { ExternalEditorState::Active => Self::handle_input_active(input_handler), ExternalEditorState::Empty => self.handle_input_empty(input_handler), - _ => HandleInputResult::new(Input::Other), + _ => ProcessResult::new().input(Input::Other), } } } @@ -129,21 +128,21 @@ impl<'e> ExternalEditor<'e> { } fn process_active(&mut self, git_interactive: &GitInteractive) -> ProcessResult { - let mut result = ProcessResultBuilder::new(); + let mut result = ProcessResult::new(); if let Err(e) = self.run_editor(git_interactive) { - result = result.error(e.as_str(), State::ExternalEditor); + result = result.error(e.as_str()); self.state = ExternalEditorState::Error; } else { self.state = ExternalEditorState::Finish; } - result.build() + result } fn process_finish(&mut self, git_interactive: &mut GitInteractive) -> ProcessResult { - let mut result = ProcessResultBuilder::new(); + let mut result = ProcessResult::new(); if let Err(e) = git_interactive.reload_file() { - result = result.error(e.as_str(), State::ExternalEditor); + result = result.error(e.as_str()); self.state = ExternalEditorState::Error; } else if git_interactive.get_lines().is_empty() { @@ -152,11 +151,11 @@ impl<'e> ExternalEditor<'e> { else { result = result.state(State::List); } - result.build() + result } fn process_error(git_interactive: &GitInteractive) -> ProcessResult { - let mut result = ProcessResultBuilder::new().state(State::Exiting); + let mut result = ProcessResult::new().state(State::Exiting); if git_interactive.get_lines().is_empty() { result = result.exit_status(ExitStatus::Good); @@ -164,23 +163,23 @@ impl<'e> ExternalEditor<'e> { else { result = result.exit_status(ExitStatus::StateError); } - result.build() + result } - fn handle_input_active(input_handler: &InputHandler<'_>) -> HandleInputResult { + fn handle_input_active(input_handler: &InputHandler<'_>) -> ProcessResult { let input = input_handler.get_input(InputMode::Default); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); if let Input::Resize = input { } else { result = result.state(State::List); } - result.build() + result } - fn handle_input_empty(&mut self, input_handler: &InputHandler<'_>) -> HandleInputResult { + fn handle_input_empty(&mut self, input_handler: &InputHandler<'_>) -> ProcessResult { let input = input_handler.get_input(InputMode::Confirm); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); match input { Input::Yes => { result = result.exit_status(ExitStatus::Good).state(State::Exiting); @@ -191,6 +190,6 @@ impl<'e> ExternalEditor<'e> { }, _ => {}, } - result.build() + result } } diff --git a/src/list/mod.rs b/src/list/mod.rs index 9d27d7a..372950c 100644 --- a/src/list/mod.rs +++ b/src/list/mod.rs @@ -18,7 +18,6 @@ use crate::list::utils::{ get_visual_footer_full, }; use crate::process::exit_status::ExitStatus; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; use crate::process::process_result::ProcessResult; use crate::process::state::State; @@ -108,11 +107,11 @@ impl<'l> ProcessModule for List<'l> { input_handler: &InputHandler<'_>, git_interactive: &mut GitInteractive, view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { let (_, view_height) = view.get_view_size(); let input = input_handler.get_input(InputMode::List); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); match input { Input::MoveCursorLeft => self.view_data.scroll_left(), Input::MoveCursorRight => self.view_data.scroll_right(), @@ -131,7 +130,7 @@ impl<'l> ProcessModule for List<'l> { } let selected_index = *git_interactive.get_selected_line_index() - 1; self.view_data.ensure_line_visible(selected_index); - result.build() + result } fn get_help_keybindings_descriptions(&self) -> Option<&[(&str, &str)]> { @@ -173,9 +172,9 @@ impl<'l> List<'l> { fn handle_normal_mode_input( &mut self, input: Input, - result: HandleInputResultBuilder, + result: ProcessResult, git_interactive: &mut GitInteractive, - ) -> HandleInputResultBuilder + ) -> ProcessResult { let mut result = result; match input { @@ -226,9 +225,9 @@ impl<'l> List<'l> { fn handle_visual_mode_input( &mut self, input: Input, - result: HandleInputResultBuilder, + result: ProcessResult, git_interactive: &mut GitInteractive, - ) -> HandleInputResultBuilder + ) -> ProcessResult { let mut result = result; match input { diff --git a/src/main.rs b/src/main.rs index 3efe38b..fe59dbb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,6 @@ mod confirm_rebase; mod constants; mod display; mod edit; -mod error; mod exiting; mod external_editor; mod git_interactive; diff --git a/src/process/error.rs b/src/process/error.rs new file mode 100644 index 0000000..65e4766 --- /dev/null +++ b/src/process/error.rs @@ -0,0 +1,29 @@ +use crate::input::input_handler::{InputHandler, InputMode}; +use crate::process::process_result::ProcessResult; +use crate::view::view_data::ViewData; +use crate::view::View; + +pub struct Error { + view_data: ViewData, +} + +impl Error { + pub fn new(message: &str) -> Self { + Self { + view_data: ViewData::new_error(message), + } + } + + pub fn get_view_data(&mut self, view: &View<'_>) -> &ViewData { + let (view_width, view_height) = view.get_view_size(); + self.view_data.set_view_size(view_width, view_height); + self.view_data.rebuild(); + &self.view_data + } + + #[allow(clippy::unused_self)] + pub fn handle_input(&mut self, input_handler: &InputHandler<'_>) -> ProcessResult { + let input = input_handler.get_input(InputMode::Default); + ProcessResult::new().input(input) + } +} diff --git a/src/process/handle_input_result.rs b/src/process/handle_input_result.rs deleted file mode 100644 index 9f63ee6..0000000 --- a/src/process/handle_input_result.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::input::Input; -use crate::process::exit_status::ExitStatus; -use crate::process::state::State; - -#[derive(Debug, PartialEq)] -pub struct HandleInputResult { - pub(super) exit_status: Option, - pub(super) input: Input, - pub(super) state: Option, -} - -impl HandleInputResult { - pub(crate) const fn new(input: Input) -> Self { - Self { - exit_status: None, - input, - state: None, - } - } -} - -pub struct HandleInputResultBuilder { - handle_input: HandleInputResult, -} - -impl HandleInputResultBuilder { - pub(crate) const fn new(input: Input) -> Self { - Self { - handle_input: HandleInputResult { - exit_status: None, - input, - state: None, - }, - } - } - - pub(crate) const fn exit_status(mut self, status: ExitStatus) -> Self { - self.handle_input.exit_status = Some(status); - self - } - - #[allow(clippy::missing_const_for_fn)] - pub(crate) fn state(mut self, new_state: State) -> Self { - self.handle_input.state = Some(new_state); - self - } - - #[allow(clippy::missing_const_for_fn)] - pub(crate) fn build(self) -> HandleInputResult { - self.handle_input - } -} diff --git a/src/process/help.rs b/src/process/help.rs index 304ea4c..4be9cdd 100644 --- a/src/process/help.rs +++ b/src/process/help.rs @@ -1,7 +1,7 @@ use crate::display::display_color::DisplayColor; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; -use crate::process::handle_input_result::HandleInputResult; +use crate::process::process_result::ProcessResult; use crate::view::line_segment::LineSegment; use crate::view::view_data::ViewData; use crate::view::view_line::ViewLine; @@ -84,7 +84,7 @@ impl Help { &self.view_data } - pub fn handle_input(&mut self, input_handler: &InputHandler<'_>, view: &View<'_>) -> HandleInputResult { + pub fn handle_input(&mut self, input_handler: &InputHandler<'_>, view: &View<'_>) -> ProcessResult { let input = input_handler.get_input(InputMode::Default); match input { Input::MoveCursorLeft => self.view_data.scroll_left(), @@ -97,8 +97,8 @@ impl Help { let (view_width, view_height) = view.get_view_size(); self.view_data.set_view_size(view_width, view_height); }, - _ => return HandleInputResult::new(Input::Help), + _ => return ProcessResult::new().input(Input::Help), } - HandleInputResult::new(input) + ProcessResult::new().input(input) } } diff --git a/src/process/mod.rs b/src/process/mod.rs index b794856..039c2cc 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -1,5 +1,5 @@ +mod error; pub mod exit_status; -pub mod handle_input_result; mod help; pub mod process_module; pub mod process_result; @@ -13,16 +13,17 @@ use crate::confirm_rebase::ConfirmRebase; use crate::constants::{MINIMUM_COMPACT_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT}; use crate::display::Display; use crate::edit::Edit; -use crate::error::Error; use crate::exiting::Exiting; use crate::external_editor::ExternalEditor; use crate::git_interactive::GitInteractive; use crate::input::input_handler::InputHandler; use crate::input::Input; use crate::list::List; +use crate::process::error::Error; use crate::process::exit_status::ExitStatus; use crate::process::help::Help; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::show_commit::ShowCommit; use crate::view::View; @@ -32,7 +33,7 @@ pub struct Process<'r> { confirm_abort: ConfirmAbort, confirm_rebase: ConfirmRebase, edit: Edit, - error: Error, + error: Option, exit_status: Option, exiting: Exiting, external_editor: ExternalEditor<'r>, @@ -59,7 +60,7 @@ impl<'r> Process<'r> { confirm_abort: ConfirmAbort::new(), confirm_rebase: ConfirmRebase::new(), edit: Edit::new(), - error: Error::new(), + error: None, exit_status: None, exiting: Exiting::new(), external_editor: ExternalEditor::new(display, config.git.editor.as_str()), @@ -77,7 +78,9 @@ impl<'r> Process<'r> { pub(crate) fn run(&mut self) -> Result, String> { self.check_window_size(); while self.exit_status.is_none() { - self.process(); + if self.help.is_none() && self.error.is_none() { + self.process(); + } self.render(); self.handle_input(); } @@ -90,7 +93,6 @@ impl<'r> Process<'r> { State::ConfirmAbort => self.confirm_abort.activate(&self.state, &self.git_interactive), State::ConfirmRebase => self.confirm_rebase.activate(&self.state, &self.git_interactive), State::Edit => self.edit.activate(&self.state, &self.git_interactive), - State::Error { .. } => self.error.activate(&self.state, &self.git_interactive), State::Exiting => self.exiting.activate(&self.state, &self.git_interactive), State::ExternalEditor => self.external_editor.activate(&self.state, &self.git_interactive), State::List => self.list.activate(&self.state, &self.git_interactive), @@ -104,7 +106,6 @@ impl<'r> Process<'r> { State::ConfirmAbort => self.confirm_abort.deactivate(), State::ConfirmRebase => self.confirm_rebase.deactivate(), State::Edit => self.edit.deactivate(), - State::Error { .. } => self.error.deactivate(), State::Exiting => self.exiting.deactivate(), State::ExternalEditor => self.external_editor.deactivate(), State::List => self.list.deactivate(), @@ -114,31 +115,18 @@ impl<'r> Process<'r> { } fn process(&mut self) { - if self.help.is_none() { - let result = match self.state { - State::ConfirmAbort => self.confirm_abort.process(&mut self.git_interactive, self.view), - State::ConfirmRebase => self.confirm_rebase.process(&mut self.git_interactive, self.view), - State::Edit => self.edit.process(&mut self.git_interactive, self.view), - State::Error { .. } => self.error.process(&mut self.git_interactive, self.view), - State::Exiting => self.exiting.process(&mut self.git_interactive, self.view), - State::ExternalEditor => self.external_editor.process(&mut self.git_interactive, self.view), - State::List => self.list.process(&mut self.git_interactive, self.view), - State::ShowCommit => self.show_commit.process(&mut self.git_interactive, self.view), - State::WindowSizeError(_) => self.window_size_error.process(&mut self.git_interactive, self.view), - }; - - if let Some(exit_status) = result.exit_status { - self.exit_status = Some(exit_status); - } - - if let Some(new_state) = result.state { - if new_state != self.state { - self.deactivate(); - self.state = new_state; - self.activate(); - } - } + let result = match self.state { + State::ConfirmAbort => self.confirm_abort.process(&mut self.git_interactive, self.view), + State::ConfirmRebase => self.confirm_rebase.process(&mut self.git_interactive, self.view), + State::Edit => self.edit.process(&mut self.git_interactive, self.view), + State::Exiting => self.exiting.process(&mut self.git_interactive, self.view), + State::ExternalEditor => self.external_editor.process(&mut self.git_interactive, self.view), + State::List => self.list.process(&mut self.git_interactive, self.view), + State::ShowCommit => self.show_commit.process(&mut self.git_interactive, self.view), + State::WindowSizeError(_) => self.window_size_error.process(&mut self.git_interactive, self.view), }; + + self.handle_process_result(result); } fn render(&mut self) { @@ -146,12 +134,14 @@ impl<'r> Process<'r> { if let Some(ref mut help) = self.help { help.get_view_data(self.view) } + else if let Some(ref mut error) = self.error { + error.get_view_data(self.view) + } else { match self.state { State::ConfirmAbort => self.confirm_abort.build_view_data(self.view, &self.git_interactive), State::ConfirmRebase => self.confirm_rebase.build_view_data(self.view, &self.git_interactive), State::Edit => self.edit.build_view_data(self.view, &self.git_interactive), - State::Error { .. } => self.error.build_view_data(self.view, &self.git_interactive), State::Exiting => self.exiting.build_view_data(self.view, &self.git_interactive), State::ExternalEditor => self.external_editor.build_view_data(self.view, &self.git_interactive), State::List => self.list.build_view_data(self.view, &self.git_interactive), @@ -164,41 +154,15 @@ impl<'r> Process<'r> { ); } - fn activate_help(&mut self) { - self.help = match self.state { - State::List => { - Some(Help::new_from_view_data( - self.list.get_help_keybindings_descriptions(), - self.list.get_help_view(), - )) - }, - State::ShowCommit => { - Some(Help::new_from_view_data( - self.show_commit.get_help_keybindings_descriptions(), - self.show_commit.get_help_view(), - )) - }, - State::ConfirmAbort - | State::ConfirmRebase - | State::Edit - | State::Error { .. } - | State::Exiting - | State::ExternalEditor - | State::WindowSizeError(_) => None, - }; - } - fn handle_input(&mut self) { - if let Some(ref mut help) = self.help { - let result = help.handle_input(self.input_handler, self.view); - match result.input { - Input::Resize => self.check_window_size(), - Input::Help => self.help = None, - _ => {}, - } + let result = if let Some(ref mut help) = self.help { + help.handle_input(self.input_handler, self.view) + } + else if let Some(ref mut error) = self.error { + error.handle_input(self.input_handler) } else { - let result = match self.state { + match self.state { State::ConfirmAbort => { self.confirm_abort .handle_input(self.input_handler, &mut self.git_interactive, self.view) @@ -211,10 +175,6 @@ impl<'r> Process<'r> { self.edit .handle_input(self.input_handler, &mut self.git_interactive, self.view) }, - State::Error { .. } => { - self.error - .handle_input(self.input_handler, &mut self.git_interactive, self.view) - }, State::Exiting => { self.exiting .handle_input(self.input_handler, &mut self.git_interactive, self.view) @@ -235,29 +195,66 @@ impl<'r> Process<'r> { self.window_size_error .handle_input(self.input_handler, &mut self.git_interactive, self.view) }, - }; - - if Input::Help == result.input { - self.activate_help(); } - else { - if let Some(exit_status) = result.exit_status { - self.exit_status = Some(exit_status); - } + }; + self.handle_process_result(result); + } - if let Some(new_state) = result.state { - if new_state != self.state { - self.deactivate(); - self.state = new_state; - self.activate(); - } - } + fn handle_process_result(&mut self, result: ProcessResult) { + if let Some(exit_status) = result.exit_status { + self.exit_status = Some(exit_status); + } + + if let Some(error_message) = result.error_message { + self.error = Some(Error::new(error_message.as_str())); + } - if Input::Resize == result.input { - self.check_window_size(); + match result.input { + Some(Input::Help) => self.toggle_help(), + Some(Input::Resize) => self.check_window_size(), + Some(_) => { + if self.error.is_some() { + self.error = None; } - } + }, + None => {}, }; + + if let Some(new_state) = result.state { + if new_state != self.state { + self.deactivate(); + self.state = new_state; + self.activate(); + } + } + } + + fn toggle_help(&mut self) { + if self.help.is_some() { + self.help = None; + } + else { + self.help = match self.state { + State::List => { + Some(Help::new_from_view_data( + self.list.get_help_keybindings_descriptions(), + self.list.get_help_view(), + )) + }, + State::ShowCommit => { + Some(Help::new_from_view_data( + self.show_commit.get_help_keybindings_descriptions(), + self.show_commit.get_help_view(), + )) + }, + State::ConfirmAbort + | State::ConfirmRebase + | State::Edit + | State::Exiting + | State::ExternalEditor + | State::WindowSizeError(_) => None, + }; + } } fn check_window_size(&mut self) { diff --git a/src/process/process_module.rs b/src/process/process_module.rs index aa5e1d8..baeb079 100644 --- a/src/process/process_module.rs +++ b/src/process/process_module.rs @@ -1,7 +1,6 @@ use crate::git_interactive::GitInteractive; use crate::input::input_handler::InputHandler; use crate::input::Input; -use crate::process::handle_input_result::HandleInputResult; use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::view_data::ViewData; @@ -23,9 +22,9 @@ pub trait ProcessModule { _input_handler: &InputHandler<'_>, _git_interactive: &mut GitInteractive, _view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { - HandleInputResult::new(Input::Other) + ProcessResult::new().input(Input::Other) } fn get_help_keybindings_descriptions(&self) -> Option<&[(&str, &str)]> { diff --git a/src/process/process_result.rs b/src/process/process_result.rs index edd038f..939fc8f 100644 --- a/src/process/process_result.rs +++ b/src/process/process_result.rs @@ -1,56 +1,43 @@ +use crate::input::Input; use crate::process::exit_status::ExitStatus; use crate::process::state::State; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct ProcessResult { + pub(super) error_message: Option, pub(super) exit_status: Option, + pub(super) input: Option, pub(super) state: Option, } impl ProcessResult { pub(crate) const fn new() -> Self { Self { + error_message: None, exit_status: None, + input: None, state: None, } } -} - -pub struct ProcessResultBuilder { - process_result: ProcessResult, -} -impl ProcessResultBuilder { - pub(crate) const fn new() -> Self { - Self { - process_result: ProcessResult { - exit_status: None, - state: None, - }, - } + pub(crate) const fn input(mut self, input: Input) -> Self { + self.input = Some(input); + self } - pub(crate) fn error(mut self, message: &str, return_state: State) -> Self { - self.process_result.state = Some(State::Error { - return_state: Box::new(return_state), - message: String::from(message), - }); + pub(crate) fn error(mut self, message: &str) -> Self { + self.error_message = Some(String::from(message)); self } pub(crate) const fn exit_status(mut self, status: ExitStatus) -> Self { - self.process_result.exit_status = Some(status); + self.exit_status = Some(status); self } - #[allow(clippy::missing_const_for_fn)] + #[allow(clippy::missing_const_for_fn)] // false positive pub(crate) fn state(mut self, new_state: State) -> Self { - self.process_result.state = Some(new_state); + self.state = Some(new_state); self } - - #[allow(clippy::missing_const_for_fn)] - pub(crate) fn build(self) -> ProcessResult { - self.process_result - } } diff --git a/src/process/state.rs b/src/process/state.rs index 2445ccb..228dc02 100644 --- a/src/process/state.rs +++ b/src/process/state.rs @@ -3,7 +3,6 @@ pub enum State { ConfirmAbort, ConfirmRebase, Edit, - Error { return_state: Box, message: String }, Exiting, ExternalEditor, List, diff --git a/src/process/testutil.rs b/src/process/testutil.rs index 965f65c..f515ae4 100644 --- a/src/process/testutil.rs +++ b/src/process/testutil.rs @@ -7,8 +7,8 @@ use crate::input::input_handler::InputHandler; use crate::input::Input; use crate::list::line::Line; use crate::process::exit_status::ExitStatus; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::view::testutil::render_view_data; use crate::view::View; @@ -263,20 +263,20 @@ macro_rules! process_module_handle_input_test { } pub fn _assert_handle_input_result( - actual: &HandleInputResult, + actual: &ProcessResult, input: Input, state: Option, exit_status: Option, ) { - let mut expected = HandleInputResultBuilder::new(input); + let mut expected = ProcessResult::new().input(input); if let Some(state) = state { expected = expected.state(state); } if let Some(exit_status) = exit_status { expected = expected.exit_status(exit_status); } - assert_eq!(actual, &expected.build()); + assert_eq!(actual, &expected); } #[macro_export] diff --git a/src/show_commit/mod.rs b/src/show_commit/mod.rs index 4ad8c42..73ecf68 100644 --- a/src/show_commit/mod.rs +++ b/src/show_commit/mod.rs @@ -17,9 +17,8 @@ use crate::display::display_color::DisplayColor; use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; use crate::input::Input; -use crate::process::handle_input_result::{HandleInputResult, HandleInputResultBuilder}; use crate::process::process_module::ProcessModule; -use crate::process::process_result::{ProcessResult, ProcessResultBuilder}; +use crate::process::process_result::ProcessResult; use crate::process::state::State; use crate::show_commit::commit::{Commit, LoadCommitDiffOptions}; use crate::show_commit::show_commit_state::ShowCommitState; @@ -116,15 +115,15 @@ impl<'s> ProcessModule for ShowCommit<'s> { } fn process(&mut self, _git_interactive: &mut GitInteractive, _: &View<'_>) -> ProcessResult { - let mut result = ProcessResultBuilder::new(); + // move this to active, remove the need for a cache check on each render + let mut result = ProcessResult::new(); if let Some(ref commit) = self.commit { if let Err(ref e) = *commit { - result = result.error(e.as_str(), State::List); + result = result.error(e.as_str()).state(State::List); } } - - result.build() + result } fn handle_input( @@ -132,10 +131,10 @@ impl<'s> ProcessModule for ShowCommit<'s> { input_handler: &InputHandler<'_>, _: &mut GitInteractive, _: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { let input = input_handler.get_input(InputMode::ShowCommit); - let mut result = HandleInputResultBuilder::new(input); + let mut result = ProcessResult::new().input(input); match input { Input::MoveCursorLeft => self.view_data.scroll_left(), Input::MoveCursorRight => self.view_data.scroll_right(), @@ -164,7 +163,7 @@ impl<'s> ProcessModule for ShowCommit<'s> { } }, } - result.build() + result } fn get_help_keybindings_descriptions(&self) -> Option<&[(&str, &str)]> { diff --git a/src/window_size_error/mod.rs b/src/window_size_error/mod.rs index 183cb83..d4357fb 100644 --- a/src/window_size_error/mod.rs +++ b/src/window_size_error/mod.rs @@ -1,8 +1,8 @@ use crate::constants::{MINIMUM_COMPACT_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT, MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH}; use crate::git_interactive::GitInteractive; use crate::input::input_handler::{InputHandler, InputMode}; -use crate::process::handle_input_result::HandleInputResult; use crate::process::process_module::ProcessModule; +use crate::process::process_result::ProcessResult; use crate::view::line_segment::LineSegment; use crate::view::view_data::ViewData; use crate::view::view_line::ViewLine; @@ -58,9 +58,9 @@ impl ProcessModule for WindowSizeError { input_handler: &InputHandler<'_>, _git_interactive: &mut GitInteractive, _view: &View<'_>, - ) -> HandleInputResult + ) -> ProcessResult { - HandleInputResult::new(input_handler.get_input(InputMode::Default)) + ProcessResult::new().input(input_handler.get_input(InputMode::Default)) } } -- cgit v1.2.3