use ratatui::TerminalOptions;
use super::ElementKey;
use crate::{
component::ComponentHelperExt,
props::AnyProps,
render::tree::render_loop,
terminal::{CrossTerminal, Terminal},
};
use std::{future::Future, io};
mod private {
use crate::{
component::Component,
element::{AnyElement, Element},
};
pub trait Sealed {}
impl<'a> Sealed for AnyElement<'a> {}
impl<'a, T> Sealed for Element<'a, T> where T: Component {}
impl<T: Sealed + ?Sized> Sealed for &mut T {}
}
#[doc(hidden)]
pub trait ElementRepr: private::Sealed + Sized {
fn key(&self) -> &ElementKey;
fn props_mut(&'_ mut self) -> AnyProps<'_>;
fn helper(&self) -> Box<dyn ComponentHelperExt>;
}
impl<T> ElementRepr for &mut T
where
T: ElementRepr,
{
fn key(&self) -> &ElementKey {
(**self).key()
}
fn props_mut(&'_ mut self) -> AnyProps<'_> {
(**self).props_mut()
}
fn helper(&self) -> Box<dyn ComponentHelperExt> {
(**self).helper()
}
}
pub trait ElementExt: ElementRepr {
fn render_loop(&mut self, options: TerminalOptions) -> impl Future<Output = io::Result<()>> {
async move {
let terminal = Terminal::new(CrossTerminal::with_options(options)?)?;
render_loop(self, terminal).await?;
Ok(())
}
}
fn fullscreen(&mut self) -> impl Future<Output = io::Result<()>> {
async move {
let terminal = Terminal::new(CrossTerminal::new()?)?;
render_loop(self, terminal).await?;
Ok(())
}
}
}
impl<T> ElementExt for T where T: ElementRepr {}