tui_dispatch_core/
action.rs

1//! Action trait for type-safe state mutations
2
3use std::fmt::Debug;
4use std::hash::Hash;
5
6/// Marker trait for actions that can be dispatched to the store
7///
8/// Actions represent intents to change state. They should be:
9/// - Clone: Actions may be logged, replayed, or sent to multiple handlers
10/// - Debug: For debugging and logging
11/// - Send + 'static: For async dispatch across threads
12///
13/// Use `#[derive(Action)]` from `tui-dispatch-macros` to auto-implement this trait.
14pub trait Action: Clone + Debug + Send + 'static {
15    /// Get the action name for logging and filtering
16    fn name(&self) -> &'static str;
17}
18
19/// Extension trait for actions with category support
20///
21/// This trait is auto-implemented when using `#[derive(Action)]` with
22/// `#[action(infer_categories)]`. It provides methods to query an action's
23/// category for routing and filtering.
24///
25/// # Example
26///
27/// ```ignore
28/// use tui_dispatch::ActionCategory;
29///
30/// #[derive(Action, Clone, Debug)]
31/// #[action(infer_categories)]
32/// enum MyAction {
33///     SearchStart,
34///     SearchClear,
35///     ConnectionFormOpen,
36/// }
37///
38/// let action = MyAction::SearchStart;
39/// assert_eq!(action.category(), Some("search"));
40/// assert!(matches!(action.category_enum(), MyActionCategory::Search));
41/// ```
42pub trait ActionCategory: Action {
43    /// The category enum type generated by the derive macro
44    type Category: Copy + Eq + Hash + Debug;
45
46    /// Get the action's category as a string (if categorized)
47    fn category(&self) -> Option<&'static str>;
48
49    /// Get the action's category as an enum value
50    fn category_enum(&self) -> Self::Category;
51}
52
53/// Trait for actions that provide a summary representation for logging
54///
55/// The default implementation uses the Debug representation. Override
56/// `summary()` to provide concise summaries for actions with large payloads
57/// (e.g., showing byte counts instead of full data).
58///
59/// # Example
60///
61/// ```ignore
62/// impl ActionSummary for MyAction {
63///     fn summary(&self) -> String {
64///         match self {
65///             MyAction::DidLoadData { data } => {
66///                 format!("DidLoadData {{ bytes: {} }}", data.len())
67///             }
68///             _ => format!("{:?}", self)
69///         }
70///     }
71/// }
72/// ```
73pub trait ActionSummary: Action {
74    /// Get a summary representation of this action for logging
75    ///
76    /// Should return a concise string, ideally one line, suitable for
77    /// display in a scrolling action log. For actions with large data payloads,
78    /// show size/count summaries instead of full content.
79    ///
80    /// Default implementation uses `Debug` formatting.
81    fn summary(&self) -> String {
82        format!("{:?}", self)
83    }
84}