ratatui_kit/element/
any_element.rs1use ratatui::TerminalOptions;
2
3use super::{Element, ElementKey, element_ext::ElementExt};
4use crate::{
5 component::{Component, ComponentHelper, ComponentHelperExt},
6 props::AnyProps,
7 render::tree::render_loop,
8 terminal::{CrossTerminal, Terminal},
9};
10use std::io;
11
12pub struct AnyElement<'a> {
13 key: ElementKey,
14 props: AnyProps<'a>,
15 helper: Box<dyn ComponentHelperExt>,
16}
17
18impl<'a, T> From<Element<'a, T>> for AnyElement<'a>
19where
20 T: Component,
21{
22 fn from(value: Element<'a, T>) -> Self {
23 Self {
24 key: value.key,
25 props: AnyProps::owned(value.props),
26 helper: ComponentHelper::<T>::boxed(),
27 }
28 }
29}
30
31impl<'a, 'b: 'a, T> From<&'a mut Element<'b, T>> for AnyElement<'a>
32where
33 T: Component,
34{
35 fn from(value: &'a mut Element<'b, T>) -> Self {
36 Self {
37 key: value.key.clone(),
38 props: AnyProps::borrowed(&mut value.props),
39 helper: ComponentHelper::<T>::boxed(),
40 }
41 }
42}
43
44impl<'a, 'b: 'a> From<&'a mut AnyElement<'b>> for AnyElement<'b> {
45 fn from(value: &'a mut AnyElement<'b>) -> Self {
46 Self {
47 key: value.key.clone(),
48 props: value.props.borrow(),
49 helper: value.helper.copy(),
50 }
51 }
52}
53
54impl<'a> ElementExt for AnyElement<'a> {
55 fn key(&self) -> &ElementKey {
56 &self.key
57 }
58
59 fn helper(&self) -> Box<dyn ComponentHelperExt> {
60 self.helper.copy()
61 }
62
63 fn props_mut(&'_ mut self) -> AnyProps<'_> {
64 self.props.borrow()
65 }
66
67 async fn render_loop(&mut self, options: TerminalOptions) -> io::Result<()> {
68 let terminal = Terminal::new(CrossTerminal::with_options(options)?)?;
69 render_loop(self, terminal).await?;
70 Ok(())
71 }
72
73 async fn fullscreen(&mut self) -> io::Result<()> {
74 let terminal = Terminal::new(CrossTerminal::new()?)?;
75 render_loop(self, terminal).await?;
76 Ok(())
77 }
78}
79
80impl<'a> ElementExt for &mut AnyElement<'a> {
81 fn key(&self) -> &ElementKey {
82 &self.key
83 }
84
85 fn helper(&self) -> Box<dyn ComponentHelperExt> {
86 self.helper.copy()
87 }
88
89 fn props_mut(&'_ mut self) -> AnyProps<'_> {
90 self.props.borrow()
91 }
92
93 async fn render_loop(&mut self, options: TerminalOptions) -> io::Result<()> {
94 let terminal = Terminal::new(CrossTerminal::with_options(options)?)?;
95 render_loop(&mut **self, terminal).await?;
96 Ok(())
97 }
98
99 async fn fullscreen(&mut self) -> io::Result<()> {
100 let terminal = Terminal::new(CrossTerminal::new()?)?;
101 render_loop(&mut **self, terminal).await?;
102 Ok(())
103 }
104}