Skip to main content

tui/widgets/
mod.rs

1pub mod amount;
2pub mod date;
3pub mod editor;
4pub mod select;
5pub mod splits;
6
7pub use amount::AmountWidget;
8pub use date::DateWidget;
9pub use editor::{EditMode, Editor, VimAction, VimMode};
10pub use select::{SelectOption, SelectWidget};
11pub use splits::{FocusedSubWidget, SplitRow, SplitRowPrefill, SplitsWidget};
12
13#[cfg(test)]
14mod tests;
15
16/// Discriminant for widget-first key routing without carrying widget data.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum WidgetKind {
19    Text,
20    Select,
21    Amount,
22    Date,
23    Splits,
24}
25
26/// The primary widget union — enum dispatch, no `Box<dyn>`, derives `Debug`.
27#[derive(Debug)]
28pub enum Widget {
29    Text(Editor),
30    Select(SelectWidget),
31    Amount(AmountWidget),
32    Date(DateWidget),
33    Splits(SplitsWidget),
34}
35
36impl Widget {
37    /// The submittable string value of this widget.
38    ///
39    /// Returns `""` for `Splits` (rows validated separately via [`SplitsWidget::rows`]).
40    #[must_use]
41    pub fn value(&self) -> &str {
42        match self {
43            Self::Text(ed) => ed.buffer(),
44            Self::Select(sw) => sw.value(),
45            Self::Amount(aw) => aw.value(),
46            Self::Date(dw) => dw.value(),
47            Self::Splits(_) => "",
48        }
49    }
50
51    /// The display string for rendering (label for `Select`, buffer for others).
52    #[must_use]
53    pub fn display(&self) -> String {
54        match self {
55            Self::Text(ed) => ed.buffer().to_string(),
56            Self::Select(sw) => sw.display().to_string(),
57            Self::Amount(aw) => aw.value().to_string(),
58            Self::Date(dw) => dw.value().to_string(),
59            Self::Splits(sw) => sw.display(),
60        }
61    }
62
63    /// Mutable reference to the inner [`Editor`] for `Text`, `Amount`, and
64    /// `Date` variants. Returns `None` for `Select` and `Splits`.
65    #[must_use]
66    pub fn as_text_mut(&mut self) -> Option<&mut Editor> {
67        match self {
68            Self::Text(ed) => Some(ed),
69            Self::Amount(aw) => Some(aw.as_editor_mut()),
70            Self::Date(dw) => Some(dw.as_editor_mut()),
71            Self::Select(_) | Self::Splits(_) => None,
72        }
73    }
74
75    /// Variant discriminant used for widget-first key routing decisions.
76    #[must_use]
77    pub fn kind(&self) -> WidgetKind {
78        match self {
79            Self::Text(_) => WidgetKind::Text,
80            Self::Select(_) => WidgetKind::Select,
81            Self::Amount(_) => WidgetKind::Amount,
82            Self::Date(_) => WidgetKind::Date,
83            Self::Splits(_) => WidgetKind::Splits,
84        }
85    }
86}