1use std::{convert::Infallible, fmt::Debug, pin::Pin};
2
3use futures_util::FutureExt;
4
5use crate::{Component, ComponentMessage, ComponentSender, channel::Channel};
6
7type DynComponentSender<T> =
8 Channel<ComponentMessage<<T as DynComponent>::Message, <T as DynComponent>::Event>>;
9
10trait DynComponent {
11 type Message;
12 type Event;
13 type Error: Debug;
14
15 fn start<'a>(
16 &'a mut self,
17 sender: &'a DynComponentSender<Self>,
18 ) -> Pin<Box<dyn Future<Output = Infallible> + 'a>>;
19
20 fn update_children(&mut self) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + '_>>;
21
22 fn update<'a>(
23 &'a mut self,
24 message: Self::Message,
25 sender: &'a DynComponentSender<Self>,
26 ) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + 'a>>;
27
28 fn render(&mut self, sender: &DynComponentSender<Self>) -> Result<(), Self::Error>;
29
30 fn render_children(&mut self) -> Result<(), Self::Error>;
31}
32
33impl<T: Component + 'static> DynComponent for T {
34 type Error = <T as Component>::Error;
35 type Event = <T as Component>::Event;
36 type Message = <T as Component>::Message;
37
38 fn start<'a>(
39 &'a mut self,
40 sender: &'a DynComponentSender<Self>,
41 ) -> Pin<Box<dyn Future<Output = Infallible> + 'a>> {
42 let sender = ComponentSender::<T>::from_ref(sender);
43 Box::pin(Component::start(self, sender).map(|a| a))
44 }
45
46 fn update_children(&mut self) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + '_>> {
47 Box::pin(Component::update_children(self))
48 }
49
50 fn update<'a>(
51 &'a mut self,
52 message: Self::Message,
53 sender: &'a DynComponentSender<Self>,
54 ) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + 'a>> {
55 let sender = ComponentSender::<T>::from_ref(sender);
56 Box::pin(Component::update(self, message, sender))
57 }
58
59 fn render(&mut self, sender: &DynComponentSender<Self>) -> Result<(), Self::Error> {
60 let sender = ComponentSender::<T>::from_ref(sender);
61 Component::render(self, sender)
62 }
63
64 fn render_children(&mut self) -> Result<(), Self::Error> {
65 Component::render_children(self)
66 }
67}
68
69pub struct BoxComponent<M, Ev, Err>(Box<dyn DynComponent<Message = M, Event = Ev, Error = Err>>);
75
76impl<M, Ev, Err> BoxComponent<M, Ev, Err> {
77 pub(crate) fn new<T: Component<Message = M, Event = Ev, Error = Err> + 'static>(
78 component: T,
79 ) -> Self {
80 Self(Box::new(component))
81 }
82}
83
84impl<M, Ev, Err: Debug> Component for BoxComponent<M, Ev, Err> {
85 type Error = Err;
86 type Event = Ev;
87 type Init<'a> = Infallible;
88 type Message = M;
89
90 async fn init(
91 init: Self::Init<'_>,
92 _sender: &ComponentSender<Self>,
93 ) -> Result<Self, Self::Error> {
94 match init {}
95 }
96
97 async fn start(&mut self, sender: &ComponentSender<Self>) -> ! {
98 let sender = &sender.0;
99 match self.0.start(sender).await {}
100 }
101
102 async fn update_children(&mut self) -> Result<bool, Self::Error> {
103 self.0.update_children().await
104 }
105
106 async fn update(
107 &mut self,
108 message: Self::Message,
109 sender: &ComponentSender<Self>,
110 ) -> Result<bool, Self::Error> {
111 let sender = &sender.0;
112 self.0.update(message, sender).await
113 }
114
115 fn render(&mut self, sender: &ComponentSender<Self>) -> Result<(), Self::Error> {
116 let sender = &sender.0;
117 self.0.render(sender)
118 }
119
120 fn render_children(&mut self) -> Result<(), Self::Error> {
121 self.0.render_children()
122 }
123}
124
125impl<M, Ev, Err> Debug for BoxComponent<M, Ev, Err> {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 f.debug_struct("BoxComponent").finish_non_exhaustive()
128 }
129}