ratatui_kit/element/
any_element.rs

1use 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}