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