use crate::session::{SessionId, SessionStatus};
use crate::tui::popup::LoadingOperation;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FlowContext {
Normal,
WorkspaceFlow,
IssueFlow,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum AppState {
#[default]
Normal,
WorkspacePopup,
ConfirmQuit,
ErrorPopup {
message: String,
from_popup: bool,
},
SessionTerminatedPopup {
session_id: SessionId,
exit_code: Option<i32>,
},
IssueLoading {
issue_number: u32,
phase: LoadingOperation,
},
ActionSelectPopup {
issue_number: u32,
choices: Vec<crate::github::ActionChoice>,
},
ConfirmPermissions {
branch: String,
prompt: String,
selected_yes: bool,
},
}
impl AppState {
#[must_use]
pub fn flow_context(&self) -> FlowContext {
match self {
Self::Normal | Self::ConfirmQuit | Self::SessionTerminatedPopup { .. } => {
FlowContext::Normal
}
Self::WorkspacePopup => FlowContext::WorkspaceFlow,
Self::IssueLoading { .. }
| Self::ActionSelectPopup { .. }
| Self::ConfirmPermissions { .. } => FlowContext::IssueFlow,
Self::ErrorPopup { from_popup, .. } => {
if *from_popup {
FlowContext::WorkspaceFlow
} else {
FlowContext::Normal
}
}
}
}
}
#[derive(Debug, Clone)]
pub struct SessionSnapshot {
pub id: SessionId,
pub name: String,
pub status: SessionStatus,
pub branch: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
#[rstest]
#[case(AppState::Normal, FlowContext::Normal)]
#[case(AppState::ConfirmQuit, FlowContext::Normal)]
#[case(AppState::SessionTerminatedPopup { session_id: SessionId::new_v4(), exit_code: None }, FlowContext::Normal)]
#[case(AppState::WorkspacePopup, FlowContext::WorkspaceFlow)]
#[case(AppState::IssueLoading { issue_number: 1, phase: LoadingOperation::FetchingIssue { issue_number: 1 } }, FlowContext::IssueFlow)]
#[case(AppState::ActionSelectPopup { issue_number: 1, choices: vec![] }, FlowContext::IssueFlow)]
#[case(AppState::ConfirmPermissions { branch: String::new(), prompt: String::new(), selected_yes: false }, FlowContext::IssueFlow)]
#[case(AppState::ErrorPopup { message: String::new(), from_popup: true }, FlowContext::WorkspaceFlow)]
#[case(AppState::ErrorPopup { message: String::new(), from_popup: false }, FlowContext::Normal)]
fn flow_context_mapping(#[case] state: AppState, #[case] expected: FlowContext) {
assert_eq!(state.flow_context(), expected);
}
}