// src/state/app/buffer.rs /// Represents the distinct views or "buffers" the user can navigate. #[derive(Debug, Clone, PartialEq, Eq)] pub enum AppView { Intro, Login, Register, Admin, Form(String), Scratch, } impl AppView { /// Returns the display name for the view. pub fn display_name(&self) -> &str { match self { AppView::Intro => "Intro", AppView::Login => "Login", AppView::Register => "Register", AppView::Admin => "Admin Panel", AppView::Form(name) => name.as_str(), AppView::Scratch => "*scratch*", } } } /// Holds the state related to buffer management (navigation history). #[derive(Debug, Clone)] pub struct BufferState { pub history: Vec, pub active_index: usize, } impl Default for BufferState { fn default() -> Self { Self { history: vec![AppView::Intro], // Start with Intro view active_index: 0, } } } impl BufferState { /// Updates the buffer history and active index. /// If the view already exists, it sets it as active. /// Otherwise, it adds the new view and makes it active. pub fn update_history(&mut self, view: AppView) { let existing_pos = self.history.iter().position(|v| v == &view); match existing_pos { Some(pos) => { self.active_index = pos; } None => { self.history.push(view.clone()); self.active_index = self.history.len() - 1; } } } /// Gets the currently active view. pub fn get_active_view(&self) -> Option<&AppView> { self.history.get(self.active_index) } /// Removes the currently active buffer from the history, unless it's the Intro buffer. /// Sets the new active buffer to the one preceding the closed one. /// # Returns /// * `true` if a non-Intro buffer was closed. /// * `false` if the active buffer was Intro or only Intro remained. pub fn close_active_buffer(&mut self) -> bool { let current_index = self.active_index; // Rule 1: Cannot close Intro buffer. if matches!(self.history.get(current_index), Some(AppView::Intro)) { return false; } // Rule 2: Cannot close if only Intro would remain (or already remains). // This check implicitly covers the case where len <= 1. if self.history.len() <= 1 { return false; } self.history.remove(current_index); self.active_index = current_index.saturating_sub(1).min(self.history.len() - 1); true } }