1use std::future::Future;
42
43use futures_signals::signal::{self, Always, Signal, SignalExt};
44
45pub struct Sig<T>(pub T);
49
50pub struct Val<T>(pub T);
55
56pub trait RefSignalOrValue<'a> {
58 type Item: 'a;
60 type Signal: Signal<Item = Self::Item> + 'a;
62 type Map<'b, F, R>: RefSignalOrValue<'b, Item = R> + 'b
68 where
69 'b: 'a,
70 F: FnMut(Self::Item) -> R + 'b,
71 R: RefSignalOrValue<'b, Item = R> + 'b;
72
73 fn map<'b: 'a, F, R>(self, callback: F) -> Self::Map<'b, F, R>
75 where
76 R: RefSignalOrValue<'b, Item = R> + 'b,
77 F: FnMut(Self::Item) -> R + 'b;
78
79 fn select<FVal, FSig, Data, Out>(self, fn_val: FVal, fn_sig: FSig, data: Data) -> Out
88 where
89 FVal: FnOnce(Data, Self::Item) -> Out,
90 FSig: FnOnce(Data, Self::Signal) -> Out,
91 Self: Sized;
92
93 fn select_spawn<FVal, FSig, Task, Exec>(self, fn_val: FVal, fn_sig: FSig, executor: &mut Exec)
104 where
105 FVal: FnOnce(&mut Exec, Self::Item),
106 FSig: FnOnce(&mut Exec, Self::Signal) -> Task,
107 Task: Future<Output = ()> + 'a,
108 Exec: Executor;
109}
110
111pub trait SignalOrValue: RefSignalOrValue<'static> {}
113
114impl<T: RefSignalOrValue<'static>> SignalOrValue for T {}
115
116pub trait Executor {
118 fn spawn(&mut self, future: impl Future<Output = ()> + 'static);
119}
120
121pub trait RefValue<'a> {}
123
124pub trait Value: RefValue<'static> {}
126
127impl<T: Value> RefValue<'static> for T {}
128
129macro_rules! static_values{
130 ($($t:ty),*) => {
131 $(
132 impl Value for $t {}
133 )*
134 }
135}
136
137static_values!(i8, i16, i32, i64);
138static_values!(u8, u16, u32, u64);
139static_values!(f32, f64);
140static_values!(bool, String);
141
142impl<'a> RefValue<'a> for &'a str {}
143impl<'a> RefValue<'a> for &'a String {}
144impl<'a, T: 'a> RefValue<'a> for Option<T> {}
145impl<'a, T: 'a> RefValue<'a> for [T] {}
146impl<'a, T: 'a> RefValue<'a> for &'a [T] {}
147impl<'a, const COUNT: usize, T: 'a> RefValue<'a> for [T; COUNT] {}
148
149impl RefValue<'_> for () {}
150
151macro_rules! tuple_values {
152 ($t:ident $(,)?) => {};
153 ($t0:ident, $t1:ident $(, $tail:ident)* $(,)?) => {
154 impl<'a, $t0, $t1 $(, $tail)*> RefValue<'a> for ($t0, $t1 $(, $tail)*) {}
155
156 tuple_values!($t1, $($tail),*);
157 }
158}
159
160tuple_values!(A, B, C, D, E, F, G, H, I, J);
161
162impl<'a, T> RefSignalOrValue<'a> for T
163where
164 T: RefValue<'a> + 'a,
165{
166 type Item = Self;
167 type Map<'b, F, R>
168 = R
169 where
170 'b: 'a,
171 F: FnMut(Self::Item) -> R + 'b,
172 R: RefSignalOrValue<'b, Item = R> + 'b;
173 type Signal = Always<Self::Item>;
174
175 fn map<'b: 'a, F, R>(self, mut callback: F) -> Self::Map<'b, F, R>
176 where
177 R: RefSignalOrValue<'b, Item = R> + 'b,
178 F: FnMut(Self::Item) -> R + 'b,
179 {
180 callback(self)
181 }
182
183 fn select<FVal, FSig, Data, Out>(self, fn_val: FVal, _fn_sig: FSig, data: Data) -> Out
184 where
185 FVal: FnOnce(Data, Self::Item) -> Out,
186 FSig: FnOnce(Data, Self::Signal) -> Out,
187 {
188 fn_val(data, self)
189 }
190
191 fn select_spawn<FVal, FSig, Task, Exec>(self, fn_val: FVal, _fn_sig: FSig, executor: &mut Exec)
192 where
193 FVal: FnOnce(&mut Exec, Self::Item),
194 FSig: FnOnce(&mut Exec, Self::Signal) -> Task,
195 Task: Future<Output = ()> + 'a,
196 Exec: Executor,
197 {
198 fn_val(executor, self)
199 }
200}
201
202impl<'a, T> RefSignalOrValue<'a> for Val<T>
203where
204 T: 'static,
205{
206 type Item = T;
207 type Map<'b, F, R>
208 = R
209 where
210 'b: 'a,
211 F: FnMut(Self::Item) -> R + 'b,
212 R: RefSignalOrValue<'b, Item = R> + 'b;
213 type Signal = Always<Self::Item>;
214
215 fn map<'b: 'a, F, R>(self, mut callback: F) -> Self::Map<'b, F, R>
216 where
217 R: RefSignalOrValue<'b, Item = R> + 'b,
218 F: FnMut(Self::Item) -> R + 'b,
219 {
220 callback(self.0)
221 }
222
223 fn select<FVal, FSig, Data, Out>(self, fn_val: FVal, _fn_sig: FSig, data: Data) -> Out
224 where
225 FVal: FnOnce(Data, Self::Item) -> Out,
226 FSig: FnOnce(Data, Self::Signal) -> Out,
227 {
228 fn_val(data, self.0)
229 }
230
231 fn select_spawn<FVal, FSig, Task, Exec>(self, fn_val: FVal, _fn_sig: FSig, executor: &mut Exec)
232 where
233 FVal: FnOnce(&mut Exec, Self::Item),
234 FSig: FnOnce(&mut Exec, Self::Signal) -> Task,
235 Task: Future<Output = ()> + 'a,
236 Exec: Executor,
237 {
238 fn_val(executor, self.0)
239 }
240}
241
242impl<T, S> RefSignalOrValue<'static> for Sig<S>
243where
244 T: 'static,
245 S: Signal<Item = T> + 'static,
246{
247 type Item = T;
248 type Map<'b, F, R>
249 = Sig<signal::Map<S, F>>
250 where
251 'b: 'static,
252 F: FnMut(Self::Item) -> R + 'b,
253 R: RefSignalOrValue<'b, Item = R> + 'b;
254 type Signal = S;
255
256 fn map<'b, F, R>(self, callback: F) -> Self::Map<'b, F, R>
257 where
258 'b: 'static,
259 R: RefSignalOrValue<'b, Item = R> + 'b,
260 F: FnMut(Self::Item) -> R + 'b,
261 {
262 Sig(self.0.map(callback))
263 }
264
265 fn select<FVal, FSig, Data, Out>(self, _fn_val: FVal, fn_sig: FSig, data: Data) -> Out
266 where
267 FVal: FnOnce(Data, Self::Item) -> Out,
268 FSig: FnOnce(Data, Self::Signal) -> Out,
269 {
270 fn_sig(data, self.0)
271 }
272
273 fn select_spawn<FVal, FSig, Task, Exec>(self, _fn_val: FVal, fn_sig: FSig, executor: &mut Exec)
274 where
275 FVal: FnOnce(&mut Exec, Self::Item),
276 FSig: FnOnce(&mut Exec, Self::Signal) -> Task,
277 Task: Future<Output = ()> + 'static,
278 Exec: Executor,
279 {
280 let future = fn_sig(executor, self.0);
281 executor.spawn(future)
282 }
283}