pub struct Application<CID, SID, CA, CS, CM>{ /* private fields */ }Expand description
Application is the struct that will hold all the parts of your TUI application.
It will hold
- the [
Args] given on the command line - the [
TUI] - to manage the lifecycle and handle user inputs - the
View- to draw your [Component]s - the
Port- to handle external messages sent from [Ship]s - the [
Subscriptions] - to register what Event your [Component]s and [Ship]s may accept - a copy of the
Senderchannel so we can send messages
§Example
//! A basic example of a TUI application using ez-tui.
mod actions_list;
use crate::actions_list::ActionsListCpt;
use ez_tui::{Application, EzCptIds, FocusChain, LayoutItem, NoClientShipId};
use ez_tui::{CustomLayout, View};
use ez_tui::{Error, NoClientArgs, NoClientMsg, NoClientState};
use ratatui::layout::Layout;
use ratatui_macros::constraints;
use std::collections::VecDeque;
use std::process::ExitCode;
use strum_macros::EnumIter;
/// Examples components ids
#[derive(Ord, PartialOrd, PartialEq, Eq, Clone, Debug, Hash, Default, EnumIter)]
pub enum MyCptIds {
/// A dummy
#[default]
Dummy,
}
impl EzCptIds for MyCptIds {}
impl FocusChain for MyCptIds {}
type TuiApp = Application<MyCptIds, NoClientShipId, NoClientArgs, NoClientState, NoClientMsg>;
#[tokio::main]
async fn main() -> Result<ExitCode, Error> {
let (args, logger) = TuiApp::parse();
let mut app: TuiApp = TuiApp::init(args, logger);
let mut view = View::new();
view = view
.mount(MyCptIds::Dummy, Box::new(ActionsListCpt::default()))
.layout(CustomLayout::named(
"Main's layout",
Layout::horizontal(&constraints![*=1]),
VecDeque::from([LayoutItem::Component(MyCptIds::Dummy.into())]),
)?);
app = app.with_view(view);
app.start().await;
Ok(ExitCode::SUCCESS)
}Implementations§
Source§impl<CID, SID, CA, CM> Application<CID, SID, CA, NoClientState, CM>
Implementation for Applications that explicitly don’t use a state (uses NoClientState instead)
impl<CID, SID, CA, CM> Application<CID, SID, CA, NoClientState, CM>
Implementation for Applications that explicitly don’t use a state (uses NoClientState instead)
Sourcepub fn init(args: AppArguments<CA>, logger: LogSwitcher) -> Self
pub fn init(args: AppArguments<CA>, logger: LogSwitcher) -> Self
Create a new Application instance by parsing the command line arguments and creating a [Tui] instance.
That application will not support any custom [ClientState] and will use the default NoClientState.
If you need some global state for your business logic, you should use with_state instead.
Source§impl<CID, SID, CA, CS, CM> Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> Application<CID, SID, CA, CS, CM>
Sourcepub fn parse() -> (AppArguments<CA>, LogSwitcher)
pub fn parse() -> (AppArguments<CA>, LogSwitcher)
Wrap the clap::Parser trait to parse the command line arguments nd initialize logging from them
Sourcepub fn with_view(self, view: View<CID, CA, CS, CM>) -> Self
pub fn with_view(self, view: View<CID, CA, CS, CM>) -> Self
Set a View for this application. The view is the UI part of the application and holds all components rendered to the user.
Sourcepub fn with_port(self, port: Port<CID, SID, CA, CS, CM>) -> Self
pub fn with_port(self, port: Port<CID, SID, CA, CS, CM>) -> Self
Set a Port for this application. The port is the interface to the outside world; any data you expect to receive from an external source should be emited in a [Ship]. The port will holds all those ships.
Sourcepub fn with_global_key_codes(self, hk: GlobalHotKeys) -> Self
pub fn with_global_key_codes(self, hk: GlobalHotKeys) -> Self
Set the global key codes for this application.
Sourcepub fn init_with_state(
args: AppArguments<CA>,
logger: LogSwitcher,
client_state: CS,
) -> Self
pub fn init_with_state( args: AppArguments<CA>, logger: LogSwitcher, client_state: CS, ) -> Self
Same as init but with a custom [ClientState]
Sourcepub fn get_args(&self) -> AppArguments<CA>
pub fn get_args(&self) -> AppArguments<CA>
Get the original command line arguments
Sourcepub async fn start(&mut self)
pub async fn start(&mut self)
Start the application lifecycle
§Panics
If any of those things fails to initialize:
- The TUI cannot be entered
- The channel to send events is already closed
Sourcepub fn subscribe_cpt(
self,
id: &EzCptId<CID>,
subs: Vec<(EventClause<CID, CM>, SubClause<CID, SID>)>,
) -> Self
pub fn subscribe_cpt( self, id: &EzCptId<CID>, subs: Vec<(EventClause<CID, CM>, SubClause<CID, SID>)>, ) -> Self
Subscribe a [Component] to a list of Event via a [Sub] struct.
A Sub describes what kind of event and in under what circumstances the component should be notified.
Sourcepub fn subscribe_ship(
self,
id: EzShipId<SID>,
subs: Vec<(EventClause<CID, CM>, SubClause<CID, SID>)>,
) -> Self
pub fn subscribe_ship( self, id: EzShipId<SID>, subs: Vec<(EventClause<CID, CM>, SubClause<CID, SID>)>, ) -> Self
Subscribe a [Ship] to a list of Event via a [Sub] struct.
A Sub describes what kind of event and in under what circumstances the ship should be notified.
Source§impl<CID, SID, CA, CS, CM> Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> Application<CID, SID, CA, CS, CM>
Sourcepub fn unsubscribe_component(&mut self, id: &EzCptId<CID>)
pub fn unsubscribe_component(&mut self, id: &EzCptId<CID>)
Remoove all subscriptions for a given [Component]
Sourcepub fn unsubscribe_ship(&mut self, id: &EzShipId<SID>)
pub fn unsubscribe_ship(&mut self, id: &EzShipId<SID>)
Remove all subscriptions for a given [Ship]
Sourcepub fn cpt_subscribed(
&self,
id: &EzCptId<CID>,
clause: &EventClause<CID, CM>,
) -> bool
pub fn cpt_subscribed( &self, id: &EzCptId<CID>, clause: &EventClause<CID, CM>, ) -> bool
Check whether a [Component] is subscribed to a given EventClause
Sourcepub fn port_subscribed(
&self,
id: &EzShipId<SID>,
clause: &EventClause<CID, CM>,
) -> bool
pub fn port_subscribed( &self, id: &EzShipId<SID>, clause: &EventClause<CID, CM>, ) -> bool
Check whether a [Ship] is subscribed to a given EventClause
Auto Trait Implementations§
impl<CID, SID, CA, CS, CM> !Freeze for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> !RefUnwindSafe for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> !Send for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> !Sync for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> !UnwindSafe for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> Unpin for Application<CID, SID, CA, CS, CM>
impl<CID, SID, CA, CS, CM> UnsafeUnpin for Application<CID, SID, CA, CS, CM>where
AppArguments<CA>: UnsafeUnpin,
Option<View<CID, CA, CS, CM>>: UnsafeUnpin,
Option<Port<CID, SID, CA, CS, CM>>: UnsafeUnpin,
Vec<Subscription<CID, SID, CM>>: UnsafeUnpin,
Tui<CID, CM>: UnsafeUnpin,
Sender<EzEvent<CID, CM>>: UnsafeUnpin,
Mutex<State<CS>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more