ratatui_kit/element/
element_ext.rs1use ratatui::TerminalOptions;
2
3use super::ElementKey;
4use crate::{
5 component::ComponentHelperExt,
6 props::AnyProps,
7 render::tree::render_loop,
8 terminal::{CrossTerminal, Terminal},
9};
10use std::{future::Future, io};
11
12mod private {
13 use crate::{
14 component::Component,
15 element::{AnyElement, Element},
16 };
17
18 pub trait Sealed {}
19
20 impl<'a> Sealed for AnyElement<'a> {}
21 impl<'a, T> Sealed for Element<'a, T> where T: Component {}
22 impl<T: Sealed + ?Sized> Sealed for &mut T {}
23}
24
25#[doc(hidden)]
26pub trait ElementRepr: private::Sealed + Sized {
27 fn key(&self) -> &ElementKey;
29 fn props_mut(&'_ mut self) -> AnyProps<'_>;
31 fn helper(&self) -> Box<dyn ComponentHelperExt>;
33}
34
35impl<T> ElementRepr for &mut T
36where
37 T: ElementRepr,
38{
39 fn key(&self) -> &ElementKey {
40 (**self).key()
41 }
42
43 fn props_mut(&'_ mut self) -> AnyProps<'_> {
44 (**self).props_mut()
45 }
46
47 fn helper(&self) -> Box<dyn ComponentHelperExt> {
48 (**self).helper()
49 }
50}
51
52pub trait ElementExt: ElementRepr {
59 fn render_loop(&mut self, options: TerminalOptions) -> impl Future<Output = io::Result<()>> {
61 async move {
62 let terminal = Terminal::new(CrossTerminal::with_options(options)?)?;
63 render_loop(self, terminal).await?;
64 Ok(())
65 }
66 }
67
68 fn fullscreen(&mut self) -> impl Future<Output = io::Result<()>> {
70 async move {
71 let terminal = Terminal::new(CrossTerminal::new()?)?;
72 render_loop(self, terminal).await?;
73 Ok(())
74 }
75 }
76}
77
78impl<T> ElementExt for T where T: ElementRepr {}