summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2019-06-05 09:56:22 -0230
committerGitHub <noreply@github.com>2019-06-05 09:56:22 -0230
commit15a7ddc98718862270c33cfc05fbf66c6ccd7575 (patch)
tree4f12d83711051d0b2579f5c06ace41b9f9765a12
parent0d8ac5dc228de9166e9e739f92564a8782b95d6f (diff)
parent869938aa9f5f1aab4715dfb340bf680f74858e16 (diff)
Merge pull request #136 from MitMaro/tim/process-loop
Move process loop out of application
-rw-r--r--src/application.rs173
-rw-r--r--src/main.rs6
-rw-r--r--src/process/exit_status.rs (renamed from src/exit_status.rs)0
-rw-r--r--src/process/handle_input_result.rs3
-rw-r--r--src/process/mod.rs7
-rw-r--r--src/process/process.rs103
-rw-r--r--src/process/process_module.rs25
-rw-r--r--src/process/process_result.rs3
8 files changed, 217 insertions, 103 deletions
diff --git a/src/application.rs b/src/application.rs
index 1508b04..c763e7e 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -3,13 +3,18 @@ use crate::git_interactive::GitInteractive;
use crate::config::Config;
use crate::constants::{LIST_HELP_LINES, VISUAL_MODE_HELP_LINES};
-use crate::exit_status::ExitStatus;
use crate::input::{Input, InputHandler};
-use crate::process::{HandleInputResult, HandleInputResultBuilder, ProcessResult, ProcessResultBuilder, State};
+use crate::process::{
+ ExitStatus,
+ HandleInputResult,
+ HandleInputResultBuilder,
+ ProcessResult,
+ ProcessResultBuilder,
+ State,
+};
use crate::view::View;
use crate::window::Window;
use core::borrow::Borrow;
-use std::cell::RefCell;
use std::process::Command;
use std::process::ExitStatus as ProcessExitStatus;
use unicode_segmentation::UnicodeSegmentation;
@@ -18,10 +23,8 @@ pub struct Application<'a> {
config: &'a Config,
edit_content: String,
edit_content_cursor: usize,
- exit_status: Option<ExitStatus>,
git_interactive: GitInteractive,
input_handler: &'a InputHandler<'a>,
- state: RefCell<State>,
view: View<'a>,
}
@@ -37,34 +40,56 @@ impl<'a> Application<'a> {
config,
edit_content: String::from(""),
edit_content_cursor: 0,
- exit_status: None,
git_interactive,
input_handler,
- state: RefCell::new(State::List),
view,
}
}
- pub fn run(&mut self) -> Result<Option<ExitStatus>, String> {
- self.handle_resize();
- while self.exit_status.is_none() {
- // process based on input, allowed to change state
- self.process();
- // draw output for state, including state change from process
- self.draw();
- // handle input for state
- self.handle_input();
+ fn get_cursor_index(&self) -> usize {
+ *self.git_interactive.get_selected_line_index() - 1
+ }
+
+ pub fn activate(&mut self, state: State) {
+ match state {
+ State::ConfirmAbort => {},
+ State::ConfirmRebase => {},
+ State::Edit => {},
+ State::EditFinish => {},
+ State::Error { .. } => {},
+ State::Exiting => {},
+ State::ExternalEditor(_) => {},
+ State::ExternalEditorError => {},
+ State::ExternalEditorFinish(_) => {},
+ State::Help(_) => {},
+ State::List => {},
+ State::ShowCommit => {},
+ State::VisualMode => {},
+ State::WindowSizeError(_) => {},
}
- self.exit_end()?;
- Ok(self.exit_status)
}
- fn get_cursor_index(&self) -> usize {
- *self.git_interactive.get_selected_line_index() - 1
+ pub fn deactivate(&mut self, state: State) {
+ match state {
+ State::ConfirmAbort => {},
+ State::ConfirmRebase => {},
+ State::Edit => {},
+ State::EditFinish => {},
+ State::Error { .. } => {},
+ State::Exiting => {},
+ State::ExternalEditor(_) => {},
+ State::ExternalEditorError => {},
+ State::ExternalEditorFinish(_) => {},
+ State::Help(_) => {},
+ State::List => {},
+ State::ShowCommit => {},
+ State::VisualMode => {},
+ State::WindowSizeError(_) => {},
+ }
}
- fn process(&mut self) {
- let process_result = match self.get_state() {
+ pub fn process(&mut self, state: State) -> ProcessResult {
+ match state {
State::ConfirmAbort => ProcessResult::new(),
State::ConfirmRebase => ProcessResult::new(),
State::Edit => ProcessResult::new(),
@@ -79,23 +104,15 @@ impl<'a> Application<'a> {
State::ShowCommit => self.process_show_commit(),
State::VisualMode => self.process_list(),
State::WindowSizeError(_) => ProcessResult::new(),
- };
-
- if let Some(exit_status) = process_result.exit_status {
- self.exit_status = Some(exit_status);
- }
-
- if let Some(new_state) = process_result.state {
- self.set_state(new_state);
}
}
- fn process_edit_finish(&mut self) -> ProcessResult {
+ pub fn process_edit_finish(&mut self) -> ProcessResult {
self.git_interactive.edit_selected_line(self.edit_content.as_str());
ProcessResultBuilder::new().state(State::List).build()
}
- fn process_external_editor(&mut self, return_state: &State) -> ProcessResult {
+ pub fn process_external_editor(&mut self, return_state: &State) -> ProcessResult {
let mut result = ProcessResultBuilder::new();
result = if let Err(e) = self.run_editor() {
@@ -108,7 +125,7 @@ impl<'a> Application<'a> {
result.build()
}
- fn process_external_editor_finish(&mut self) -> ProcessResult {
+ pub fn process_external_editor_finish(&mut self) -> ProcessResult {
let mut result = ProcessResultBuilder::new();
result = if let Err(e) = self.git_interactive.reload_file(self.config.comment_char.as_str()) {
result.error(e.as_str(), State::List)
@@ -123,7 +140,7 @@ impl<'a> Application<'a> {
result.build()
}
- fn process_external_editor_error(&mut self) -> ProcessResult {
+ pub fn process_external_editor_error(&mut self) -> ProcessResult {
ProcessResultBuilder::new()
.state(State::Exiting)
.exit_status(
@@ -137,14 +154,14 @@ impl<'a> Application<'a> {
.build()
}
- fn process_list(&mut self) -> ProcessResult {
+ pub fn process_list(&mut self) -> ProcessResult {
let lines = self.git_interactive.get_lines();
let selected_index = self.get_cursor_index();
self.view.update_main_top(lines.len(), selected_index);
ProcessResult::new()
}
- fn process_show_commit(&mut self) -> ProcessResult {
+ pub fn process_show_commit(&mut self) -> ProcessResult {
let mut result = ProcessResultBuilder::new();
if let Err(e) = self.git_interactive.load_commit_stats() {
result = result.error(e.as_str(), State::List);
@@ -152,9 +169,13 @@ impl<'a> Application<'a> {
result.build()
}
- fn draw(&self) {
+ pub fn check_window_size(&self) -> bool {
+ self.view.check_window_size()
+ }
+
+ pub fn render(&self, state: State) {
self.view.clear();
- match self.get_state() {
+ match state {
State::ConfirmAbort => self.draw_confirm_abort(),
State::ConfirmRebase => self.draw_confirm_rebase(),
State::Edit => self.draw_edit(),
@@ -166,11 +187,11 @@ impl<'a> Application<'a> {
State::ExternalEditorFinish(_) => {},
State::Help(help_state) => self.draw_help(help_state.borrow()),
State::List => self.draw_main(false),
- State::VisualMode => self.draw_main(false),
+ State::VisualMode => self.draw_main(true),
State::ShowCommit => self.draw_show_commit(),
State::WindowSizeError(_) => self.draw_window_size_error(),
}
- self.view.refresh();
+ self.view.refresh()
}
fn draw_confirm_abort(&self) {
@@ -226,19 +247,6 @@ impl<'a> Application<'a> {
self.view.draw_window_size_error();
}
- fn handle_resize(&self) {
- let check = self.view.check_window_size();
- let state = self.get_state();
- if let State::WindowSizeError(return_state) = state {
- if check {
- self.set_state(*return_state);
- }
- }
- else if !check {
- self.set_state(State::WindowSizeError(Box::new(self.get_state())));
- }
- }
-
fn get_input(&self) -> Input {
self.input_handler.get_input()
}
@@ -251,34 +259,22 @@ impl<'a> Application<'a> {
self.input_handler.get_character()
}
- fn handle_input(&mut self) {
- let result = match self.get_state() {
+ pub fn handle_input(&mut self, state: State) -> HandleInputResult {
+ match state {
State::ConfirmAbort => self.handle_confirm_abort_input(),
State::ConfirmRebase => self.handle_confirm_rebase_input(),
State::Edit => self.handle_edit(),
- State::EditFinish => return,
+ State::EditFinish => HandleInputResult::new(Input::Other),
State::Error { return_state, .. } => self.handle_error_input(return_state.borrow()),
- State::Exiting => return,
+ State::Exiting => HandleInputResult::new(Input::Other),
State::ExternalEditor(return_state) => self.handle_external_editor_input(return_state.borrow()),
- State::ExternalEditorError => return,
- State::ExternalEditorFinish(_) => return,
+ State::ExternalEditorError => HandleInputResult::new(Input::Other),
+ State::ExternalEditorFinish(_) => HandleInputResult::new(Input::Other),
State::Help(help_state) => self.handle_help_input(help_state.borrow()),
State::List => self.handle_list_input(),
State::VisualMode => self.handle_visual_mode_input(),
State::ShowCommit => self.handle_show_commit_input(),
State::WindowSizeError(_) => self.handle_window_size_error_input(),
- };
-
- if let Some(exit_status) = result.exit_status {
- self.exit_status = Some(exit_status);
- }
-
- if let Some(new_state) = result.state {
- self.set_state(new_state);
- }
-
- if let Input::Resize = result.input {
- self.handle_resize();
}
}
@@ -466,7 +462,7 @@ impl<'a> Application<'a> {
result.build()
}
- fn handle_error_input(&mut self, return_state: &State) -> HandleInputResult {
+ pub fn handle_error_input(&mut self, return_state: &State) -> HandleInputResult {
let input = self.get_input();
let mut result = HandleInputResultBuilder::new(input);
match input {
@@ -478,7 +474,7 @@ impl<'a> Application<'a> {
result.build()
}
- fn handle_external_editor_input(&mut self, return_state: &State) -> HandleInputResult {
+ pub fn handle_external_editor_input(&mut self, return_state: &State) -> HandleInputResult {
let input = self.get_input();
let mut result = HandleInputResultBuilder::new(input);
match input {
@@ -490,7 +486,7 @@ impl<'a> Application<'a> {
result.build()
}
- fn handle_list_input(&mut self) -> HandleInputResult {
+ pub fn handle_list_input(&mut self) -> HandleInputResult {
let input = self.get_input();
let mut result = HandleInputResultBuilder::new(input);
match input {
@@ -541,17 +537,17 @@ impl<'a> Application<'a> {
self.git_interactive.start_visual_mode();
result = result.state(State::VisualMode);
},
- Input::OpenInEditor => result = result.state(State::ExternalEditor(Box::new(self.get_state()))),
+ Input::OpenInEditor => result = result.state(State::ExternalEditor(Box::new(State::List))),
_ => {},
}
result.build()
}
- fn handle_window_size_error_input(&mut self) -> HandleInputResult {
+ pub fn handle_window_size_error_input(&mut self) -> HandleInputResult {
HandleInputResult::new(self.get_input())
}
- fn run_editor(&mut self) -> Result<(), String> {
+ pub fn run_editor(&mut self) -> Result<(), String> {
self.git_interactive.write_file()?;
let filepath = self.git_interactive.get_filepath();
let callback = || -> Result<ProcessExitStatus, String> {
@@ -576,29 +572,14 @@ impl<'a> Application<'a> {
Ok(())
}
+ pub fn write_file(&self) -> Result<(), String> {
+ self.git_interactive.write_file()
+ }
+
fn set_selected_line_action(&mut self, action: Action) {
self.git_interactive.set_selected_line_action(action);
if self.config.auto_select_next {
self.git_interactive.move_cursor_down(1);
}
}
-
- fn get_state(&self) -> State {
- self.state.borrow().clone()
- }
-
- fn set_state(&self, new_state: State) {
- self.state.replace(new_state);
- }
-
- fn exit_end(&mut self) -> Result<(), String> {
- match self.git_interactive.write_file() {
- Ok(_) => {},
- Err(msg) => {
- self.exit_status = Some(ExitStatus::FileWriteError);
- return Err(msg);
- },
- }
- Ok(())
- }
}
diff --git a/src/main.rs b/src/main.rs
index bc9b61a..f12bf25 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,7 +8,6 @@ mod color;
mod commit;
mod config;
mod constants;
-mod exit_status;
mod git_interactive;
mod input;
mod line;
@@ -19,9 +18,9 @@ mod window;
use crate::application::Application;
use crate::config::Config;
-use crate::exit_status::ExitStatus;
use crate::git_interactive::GitInteractive;
use crate::input::InputHandler;
+use crate::process::{ExitStatus, Process};
use crate::view::View;
use crate::window::Window;
@@ -78,7 +77,8 @@ fn try_main() -> Result<ExitStatus, Exit> {
let mut application = Application::new(git_interactive, View::new(&window), &input_handler, &config);
- let result = application.run();
+ let mut process = Process::new(&mut application);
+ let result = process.run();
window.end();
let exit_code = match result {
diff --git a/src/exit_status.rs b/src/process/exit_status.rs
index be4382e..be4382e 100644
--- a/src/exit_status.rs
+++ b/src/process/exit_status.rs
diff --git a/src/process/handle_input_result.rs b/src/process/handle_input_result.rs
index d1e0c85..be5e436 100644
--- a/src/process/handle_input_result.rs
+++ b/src/process/handle_input_result.rs
@@ -1,6 +1,5 @@
-use crate::exit_status::ExitStatus;
use crate::input::Input;
-use crate::process::State;
+use crate::process::{ExitStatus, State};
pub struct HandleInputResult {
pub exit_status: Option<ExitStatus>,
diff --git a/src/process/mod.rs b/src/process/mod.rs
index 9503fe9..cff53c3 100644
--- a/src/process/mod.rs
+++ b/src/process/mod.rs
@@ -1,9 +1,16 @@
+mod exit_status;
mod handle_input_result;
+#[allow(clippy::module_inception)]
+mod process;
+mod process_module;
mod process_result;
mod state;
+pub use self::exit_status::ExitStatus;
pub use self::handle_input_result::HandleInputResult;
pub use self::handle_input_result::HandleInputResultBuilder;
+pub use self::process::Process;
+pub use self::process_module::ProcessModule;
pub use self::process_result::ProcessResult;
pub use self::process_result::ProcessResultBuilder;
pub use self::state::State;
diff --git a/src/process/process.rs b/src/process/process.rs
new file mode 100644
index 0000000..5a5d00b
--- /dev/null
+++ b/src/process/process.rs
@@ -0,0 +1,103 @@
+use crate::application::Application;
+use crate::input::Input;
+use crate::process::{ExitStatus, State};
+use std::cell::RefCell;
+
+pub struct Process<'r> {
+ application: &'r mut Application<'r>,
+ exit_status: Option<ExitStatus>,
+ state: RefCell<State>,
+}
+
+impl<'r> Process<'r> {
+ pub fn new(application: &'r mut Application<'r>) -> Self {
+ Self {
+ application,
+ exit_status: None,
+ state: RefCell::new(State::List),
+ }
+ }
+
+ pub fn run(&mut self) -> Result<Option<ExitStatus>, String> {
+ self.check_window_size();
+ while self.exit_status.is_none() {
+ self.process();
+ self.render();
+ self.handle_input();
+ }
+ self.exit_end()?;
+ Ok(self.exit_status)
+ }
+
+ fn process(&mut self) {
+ let result = self.application.process(self.get_state());
+
+ 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.get_state() {
+ self.application.deactivate(self.get_state());
+ self.set_state(new_state);
+ self.application.activate(self.get_state());
+ }
+ }
+ }
+
+ fn render(&self) {
+ self.application.render(self.get_state());
+ }
+
+ fn handle_input(&mut self) {
+ let result = self.application.handle_input(self.get_state());
+
+ 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.get_state() {
+ self.application.deactivate(self.get_state());
+ self.set_state(new_state);
+ self.application.activate(self.get_state());
+ }
+ }
+
+ if let Input::Resize = result.input {
+ self.check_window_size();
+ }
+ }
+
+ fn check_window_size(&self) {
+ let check = self.application.check_window_size();
+ let state = self.get_state();
+ if let State::WindowSizeError(return_state) = state {
+ if check {
+ self.set_state(*return_state);
+ }
+ }
+ else if !check {
+ self.set_state(State::WindowSizeError(Box::new(self.get_state())));
+ }
+ }
+
+ fn set_state(&self, new_state: State) {
+ self.state.replace(new_state);
+ }
+
+ pub fn get_state(&self) -> State {
+ self.state.borrow().clone()
+ }
+
+ fn exit_end(&mut self) -> Result<(), String> {
+ match self.application.write_file() {
+ Ok(_) => {},
+ Err(msg) => {
+ self.exit_status = Some(ExitStatus::FileWriteError);
+ return Err(msg);
+ },
+ }
+ Ok(())
+ }
+}
diff --git a/src/process/process_module.rs b/src/process/process_module.rs
new file mode 100644
index 0000000..f3027d8
--- /dev/null
+++ b/src/process/process_module.rs
@@ -0,0 +1,25 @@
+use crate::git_interactive::GitInteractive;
+use crate::input::{Input, InputHandler};
+use crate::process::{HandleInputResult, ProcessResult, State};
+use crate::view::View;
+
+pub trait ProcessModule {
+ fn activate(&mut self, _state: State, _git_interactive: &GitInteractive) {}
+
+ fn deactivate(&mut self) {}
+
+ fn process(&mut self, _git_interactive: &mut GitInteractive) -> ProcessResult {
+ ProcessResult::new()
+ }
+
+ fn handle_input(
+ &mut self,
+ _input_handler: &InputHandler,
+ _git_interactive: &mut GitInteractive,
+ ) -> HandleInputResult
+ {
+ HandleInputResult::new(Input::Other)
+ }
+
+ fn render(&self, _view: &View, _git_interactive: &GitInteractive);
+}
diff --git a/src/process/process_result.rs b/src/process/process_result.rs
index b3531b2..acc4f03 100644
--- a/src/process/process_result.rs
+++ b/src/process/process_result.rs
@@ -1,5 +1,4 @@
-use crate::exit_status::ExitStatus;
-use crate::process::State;
+use crate::process::{ExitStatus, State};
#[derive(Debug)]
pub struct ProcessResult {