relm4/component/async/
connector.rs1use super::{
6 AsyncComponent, AsyncComponentController, AsyncController, stream::AsyncComponentStream,
7};
8use crate::{Receiver, Sender, ShutdownOnDrop};
9use std::fmt::{self, Debug};
10
11pub struct AsyncConnector<C: AsyncComponent> {
15 pub(super) widget: C::Root,
17
18 pub(super) sender: Sender<C::Input>,
20
21 pub(super) receiver: Receiver<C::Output>,
23
24 pub(super) shutdown_on_drop: ShutdownOnDrop,
26}
27
28impl<C: AsyncComponent> AsyncConnector<C> {
29 pub fn forward<X: 'static, F: (Fn(C::Output) -> X) + 'static>(
31 self,
32 sender_: &Sender<X>,
33 transform: F,
34 ) -> AsyncController<C> {
35 let Self {
36 widget,
37 sender,
38 receiver,
39 shutdown_on_drop,
40 } = self;
41
42 crate::spawn_local(receiver.forward(sender_.clone(), transform));
43
44 AsyncController {
45 widget,
46 sender,
47 shutdown_on_drop,
48 }
49 }
50
51 pub fn connect_receiver<F: FnMut(&mut Sender<C::Input>, C::Output) + 'static>(
53 self,
54 mut func: F,
55 ) -> AsyncController<C> {
56 let Self {
57 widget,
58 sender,
59 receiver,
60 shutdown_on_drop,
61 } = self;
62
63 let mut sender_ = sender.clone();
64 crate::spawn_local(async move {
65 while let Some(event) = receiver.recv().await {
66 func(&mut sender_, event);
67 }
68 });
69
70 AsyncController {
71 widget,
72 sender,
73 shutdown_on_drop,
74 }
75 }
76
77 pub fn detach(self) -> AsyncController<C> {
79 let Self {
80 widget,
81 sender,
82 shutdown_on_drop,
83 ..
84 } = self;
85
86 AsyncController {
87 widget,
88 sender,
89 shutdown_on_drop,
90 }
91 }
92
93 pub fn into_stream(self) -> AsyncComponentStream<C> {
96 let Self {
97 receiver,
98 shutdown_on_drop,
99 ..
100 } = self;
101
102 AsyncComponentStream {
103 stream: receiver.into_stream(),
104 shutdown_on_drop,
105 }
106 }
107}
108
109impl<C: AsyncComponent> AsyncComponentController<C> for AsyncConnector<C> {
110 fn sender(&self) -> &Sender<C::Input> {
111 &self.sender
112 }
113
114 fn widget(&self) -> &C::Root {
115 &self.widget
116 }
117
118 fn detach_runtime(&mut self) {
119 self.shutdown_on_drop.deactivate();
120 }
121}
122
123impl<C> Debug for AsyncConnector<C>
124where
125 C: AsyncComponent + Debug,
126 C::Widgets: Debug,
127{
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 f.debug_struct("Connector")
130 .field("widget", &self.widget)
131 .field("sender", &self.sender)
132 .field("receiver", &self.receiver)
133 .field("shutdown_on_drop", &self.shutdown_on_drop)
134 .finish()
135 }
136}