sauron_core/dom/
effects.rs1use crate::dom::Cmd;
2use std::future::ready;
3
4pub struct Effects<MSG, XMSG> {
12 pub local: Vec<Cmd<MSG>>,
14 pub external: Vec<Cmd<XMSG>>,
17}
18
19impl<MSG, XMSG> Effects<MSG, XMSG>
20where
21 MSG: 'static,
22{
23 pub fn new(
25 local: impl IntoIterator<Item = MSG>,
26 external: impl IntoIterator<Item = XMSG>,
27 ) -> Self
28 where
29 XMSG: 'static,
30 {
31 Self {
32 local: local.into_iter().map(|l| Cmd::once(ready(l))).collect(),
33 external: external.into_iter().map(|x| Cmd::once(ready(x))).collect(),
34 }
35 }
36
37 pub fn with_local(local: impl IntoIterator<Item = MSG>) -> Self {
39 Self {
40 local: local.into_iter().map(|l| Cmd::once(ready(l))).collect(),
41 external: vec![],
42 }
43 }
44
45 pub fn with_external(external: impl IntoIterator<Item = XMSG>) -> Self
47 where
48 XMSG: 'static,
49 {
50 Self {
51 local: vec![],
52 external: external.into_iter().map(|x| Cmd::once(ready(x))).collect(),
53 }
54 }
55
56 pub fn none() -> Self {
58 Self {
59 local: vec![],
60 external: vec![],
61 }
62 }
63
64 pub fn map_msg<F, MSG2>(self, f: F) -> Effects<MSG2, XMSG>
69 where
70 F: Fn(MSG) -> MSG2 + Clone + 'static,
71 MSG2: 'static,
72 {
73 let Effects { local, external } = self;
74 Effects {
75 local: local.into_iter().map(|l| l.map_msg(f.clone())).collect(),
76 external,
77 }
78 }
79
80 pub fn map_external<F, XMSG2>(self, f: F) -> Effects<MSG, XMSG2>
83 where
84 F: Fn(XMSG) -> XMSG2 + Clone + 'static,
85 XMSG: 'static,
86 XMSG2: 'static,
87 {
88 let Effects { local, external } = self;
89 Effects {
90 local,
91 external: external.into_iter().map(|l| l.map_msg(f.clone())).collect(),
92 }
93 }
94
95 pub fn localize<F, XMSG2>(self, f: F) -> Effects<XMSG, XMSG2>
100 where
101 F: Fn(MSG) -> XMSG + Clone + 'static,
102 XMSG: 'static,
103 XMSG2: 'static,
104 {
105 let Effects { local, external } = self;
106
107 Effects {
108 local: external
109 .into_iter()
110 .chain(local.into_iter().map(|x| x.map_msg(f.clone())))
111 .collect(),
112 external: vec![],
113 }
114 }
115
116 pub fn append_local(mut self, local: impl IntoIterator<Item = MSG>) -> Self {
118 self.local
119 .extend(local.into_iter().map(|l| Cmd::once(ready(l))));
120 self
121 }
122
123 pub fn batch(all_effects: impl IntoIterator<Item = Self>) -> Self {
125 let mut local = vec![];
126 let mut external = vec![];
127 for effect in all_effects {
128 local.extend(effect.local);
129 external.extend(effect.external);
130 }
131 Effects { local, external }
132 }
133
134 pub fn extend(
136 mut self,
137 local: impl IntoIterator<Item = MSG>,
138 external: impl IntoIterator<Item = XMSG>,
139 ) -> Self
140 where
141 XMSG: 'static,
142 {
143 self.local
144 .extend(local.into_iter().map(|l| Cmd::once(ready(l))));
145 self.external
146 .extend(external.into_iter().map(|x| Cmd::once(ready(x))));
147 self
148 }
149}
150
151impl<MSG, XMSG> From<Cmd<MSG>> for Effects<MSG, XMSG> {
152 fn from(task: Cmd<MSG>) -> Effects<MSG, XMSG> {
153 Effects {
154 local: vec![task],
155 external: vec![],
156 }
157 }
158}
159
160impl<MSG> Effects<MSG, MSG>
161where
162 MSG: 'static,
163{
164 pub fn merge(self) -> Effects<MSG, ()> {
166 let Effects { local, external } = self;
167
168 Effects {
169 local: local.into_iter().chain(external).collect(),
170 external: vec![],
171 }
172 }
173}