Lines
66.04 %
Functions
33.33 %
Branches
100 %
//! View dispatch types and traits.
pub mod config;
pub mod console;
pub mod list;
pub mod reports;
#[cfg(test)]
mod tests;
use crate::event::Intent;
use crate::tabs::config::ConfigTab;
use crate::tabs::list::ListTab;
use crate::tabs::nms::ConsoleState;
use crate::tabs::reports::ReportsTab;
use crate::widgets::EditMode;
use ratatui::Frame;
use ratatui::layout::Rect;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ViewId {
Accounts = 0,
Transactions = 1,
Commodities = 2,
Reports = 3,
Config = 4,
Console = 5,
}
impl ViewId {
pub const ALL: [ViewId; 6] = [
ViewId::Accounts,
ViewId::Transactions,
ViewId::Commodities,
ViewId::Reports,
ViewId::Config,
ViewId::Console,
];
pub fn index(self) -> usize {
self as usize
pub fn label(self) -> &'static str {
match self {
ViewId::Accounts => "Accounts",
ViewId::Transactions => "Transactions",
ViewId::Commodities => "Commodities",
ViewId::Reports => "Reports",
ViewId::Config => "Config",
ViewId::Console => "Console",
/// `Tab` is an alias so existing `Tab::Accounts`, `Tab::ALL`, etc. keep compiling.
pub type Tab = ViewId;
pub struct DrawCtx {
pub edit_mode: EditMode,
/// True when the view currently holds keyboard focus (e.g. console input active).
pub is_active: bool,
pub enum Handled {
Consumed(Vec<Cmd>),
Ignored,
pub enum Cmd {
Status(String),
SwitchView(ViewId),
/// Immutable borrow of the active tab, carrying identity on the List arm.
pub enum ViewRef<'a> {
List(ViewId, &'a ListTab),
Reports(&'a ReportsTab),
Config(&'a ConfigTab),
Console(&'a ConsoleState),
/// Mutable borrow of the active tab, carrying identity on the List arm.
pub enum ViewMut<'a> {
List(ViewId, &'a mut ListTab),
Reports(&'a mut ReportsTab),
Config(&'a mut ConfigTab),
Console(&'a mut ConsoleState),
impl<'a> ViewRef<'a> {
pub fn id(&self) -> ViewId {
ViewRef::List(id, _) => *id,
ViewRef::Reports(_) => ViewId::Reports,
ViewRef::Config(_) => ViewId::Config,
ViewRef::Console(_) => ViewId::Console,
pub fn title(&self) -> &'static str {
self.id().label()
/// Dispatch to the tab's inherent draw. The List arm passes its `ViewId`
/// label directly so the body never needs to know its own identity.
pub fn draw(&self, frame: &mut Frame, area: Rect, ctx: &DrawCtx) {
ViewRef::List(id, tab) => tab.draw(frame, area, id.label()),
ViewRef::Reports(tab) => tab.draw(frame, area),
ViewRef::Config(tab) => tab.draw(frame, area),
ViewRef::Console(tab) => tab.draw(frame, area, ctx),
impl<'a> ViewMut<'a> {
ViewMut::List(id, _) => *id,
ViewMut::Reports(_) => ViewId::Reports,
ViewMut::Config(_) => ViewId::Config,
ViewMut::Console(_) => ViewId::Console,
ViewMut::List(id, tab) => tab.draw(frame, area, id.label()),
ViewMut::Reports(tab) => tab.draw(frame, area),
ViewMut::Config(tab) => tab.draw(frame, area),
ViewMut::Console(tab) => tab.draw(frame, area, ctx),
pub fn handle(&mut self, intent: Intent, ctx: &DrawCtx) -> Handled {
ViewMut::List(_, tab) => tab.handle(intent, ctx),
ViewMut::Reports(tab) => tab.handle(intent, ctx),
ViewMut::Config(tab) => tab.handle(intent, ctx),
ViewMut::Console(tab) => tab.handle(intent, ctx),