use crate::commands::{Command, CommandResult, CommandError};
use crate::app::{AppState, Action, reducer};
use crate::services::GitService;
use tracing::instrument;
pub struct ApplyStashCommand {
pub name: String,
}
impl Command for ApplyStashCommand {
#[instrument(skip(self, git, state), fields(name = %self.name))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some("applying stash…".into())));
match git.stash_apply(&state.repo_path, &self.name, false) {
Ok(_) => {
new_state = reducer(new_state, Action::SetFeedback(Some(format!("Applied stash {}", self.name))));
new_state = reducer(new_state, Action::SetRefreshing(true));
new_state = reducer(new_state, Action::AppendOpLog(format!("applied stash {}", self.name)));
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("stash apply error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("stash apply error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}
pub struct PopStashCommand {
pub name: String,
}
impl Command for PopStashCommand {
#[instrument(skip(self, git, state), fields(name = %self.name))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some("popping stash…".into())));
match git.stash_apply(&state.repo_path, &self.name, true) {
Ok(_) => {
new_state = reducer(new_state, Action::SetFeedback(Some(format!("Popped stash {}", self.name))));
new_state = reducer(new_state, Action::SetRefreshing(true));
new_state = reducer(new_state, Action::AppendOpLog(format!("popped stash {}", self.name)));
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("stash pop error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("stash pop error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}
pub struct CreateStashCommand {
pub message: String,
}
impl Command for CreateStashCommand {
#[instrument(skip(self, git, state), fields(message = %self.message))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some("creating stash…".into())));
match git.stash_push(&state.repo_path, &self.message) {
Ok(_) => {
new_state = reducer(new_state, Action::SetFeedback(Some(format!("Created stash: {}", if self.message.is_empty() { "untitled" } else { &self.message }))));
new_state.stash_create_mode = false;
new_state.stash_message_input.clear();
new_state = reducer(new_state, Action::AppendOpLog(format!("created stash: {}", if self.message.is_empty() { "untitled" } else { &self.message })));
new_state = reducer(new_state, Action::RefreshStashes);
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("stash create error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("stash create error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}
pub struct DeleteStashCommand {
pub name: String,
}
impl Command for DeleteStashCommand {
#[instrument(skip(self, git, state), fields(name = %self.name))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some("deleting stash…".into())));
match git.stash_drop(&state.repo_path, &self.name) {
Ok(_) => {
new_state = reducer(new_state, Action::SetFeedback(Some(format!("Deleted stash {}", self.name))));
new_state = reducer(new_state, Action::AppendOpLog(format!("deleted stash {}", self.name)));
new_state = reducer(new_state, Action::RefreshStashes);
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("stash drop error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("stash drop error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}