Skip to main content

ratatui_kit/element/
element_ext.rs

1use 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    // 获取元素的唯一 key,适合 diff、重用等场景。
28    fn key(&self) -> &ElementKey;
29    // 获取并可变修改元素的属性(props)。
30    fn props_mut(&'_ mut self) -> AnyProps<'_>;
31    // 获取组件辅助操作对象,支持动态调度和扩展。
32    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
52// ElementExt trait 为所有 UI 元素提供应用入口方法。
53//
54// # 常用用法
55// ```rust
56// element!(MyComponent).fullscreen().await?;
57// ```
58pub trait ElementExt: ElementRepr {
59    // 启动渲染主循环,传入终端选项,适合自定义Viewport场景。
60    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    // 以全屏模式运行当前元素,适合大多数终端 UI 应用入口。
69    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 {}