summaryrefslogtreecommitdiffstats
path: root/src/process
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2019-06-04 20:24:30 -0230
committerTim Oram <dev@mitmaro.ca>2019-06-04 20:24:30 -0230
commit869938aa9f5f1aab4715dfb340bf680f74858e16 (patch)
tree4f12d83711051d0b2579f5c06ace41b9f9765a12 /src/process
parent0d8ac5dc228de9166e9e739f92564a8782b95d6f (diff)
Move process loop out of application
Diffstat (limited to 'src/process')
-rw-r--r--src/process/exit_status.rs20
-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
6 files changed, 157 insertions, 4 deletions
diff --git a/src/process/exit_status.rs b/src/process/exit_status.rs
new file mode 100644
index 0000000..be4382e
--- /dev/null
+++ b/src/process/exit_status.rs
@@ -0,0 +1,20 @@
+#[derive(Clone, Copy, Debug)]
+pub enum ExitStatus {
+ ConfigError,
+ FileReadError,
+ FileWriteError,
+ Good,
+ StateError,
+}
+
+impl ExitStatus {
+ pub fn to_code(self) -> i32 {
+ match self {
+ ExitStatus::ConfigError => 1,
+ ExitStatus::FileReadError => 2,
+ ExitStatus::FileWriteError => 3,
+ ExitStatus::Good => 0,
+ ExitStatus::StateError => 4,
+ }
+ }
+}
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 {