use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
pub trait SubApp<E, S> {
fn handle_input(&mut self, event: &mut E, state: &mut S);
fn render(&self, frame: &mut Frame, area: Rect, state: &mut S);
fn constraints(&self) -> Constraint;
}
#[macro_export]
macro_rules! define_sub_apps {
(
event = $event_ty:path;
state = $state_ty:path;
$( $variant:ident ( $ty:path ) => $ctor:expr ),+ $(,)?
) => {
pub enum SubAppView {
$( $variant($ty), )+
}
impl $crate::sub_app::SubApp<$event_ty, $state_ty> for SubAppView {
fn handle_input(&mut self, event: &mut $event_ty, state: &mut $state_ty) {
match self {
$(
Self::$variant(x) => {
<$ty as $crate::sub_app::SubApp<$event_ty,$state_ty>>::handle_input(
x,
event,
state,
)
}
),+
}
}
fn render(
&self,
frame: &mut $crate::ratatui::Frame,
area: $crate::ratatui::layout::Rect,
state: &mut $state_ty,
) {
match self {
$(
Self::$variant(x) => {
<$ty as $crate::sub_app::SubApp<$event_ty, $state_ty>>::render(
x,
frame,
area,
state,
)
}
),+
}
}
fn constraints(&self) -> $crate::ratatui::layout::Constraint {
match self {
$(
Self::$variant(x) => {
<$ty as $crate::sub_app::SubApp<$event_ty, $state_ty>>::constraints(x)
}
),+
}
}
}
pub fn make_app() -> $crate::eyre::Result<$crate::App<$event_ty, SubAppView, $state_ty>> {
$crate::App::new(vec![ $( SubAppView::$variant($ctor), )+ ])
}
};
}