futures_signals_ext/
ext.rs

1use futures_signals::{
2    signal::{Mutable, Signal},
3    signal_vec::{
4        Filter, FilterSignalCloned, MutableSignalVec, MutableVec, MutableVecLockMut, SignalVec,
5        SignalVecExt,
6    },
7};
8use pin_project_lite::pin_project;
9use std::{
10    collections::VecDeque,
11    hash::Hash,
12    marker::PhantomData,
13    mem,
14    pin::Pin,
15    task::{Context, Poll},
16};
17
18use crate::{Flatten, MutableVecEntry, SignalVecSpawn};
19
20#[cfg(feature = "ahash")]
21type Hasher = ahash::RandomState;
22#[cfg(not(feature = "ahash"))]
23type Hasher = std::hash::RandomState;
24
25type HashMap<K, V> = std::collections::HashMap<K, V, Hasher>;
26
27fn collect_hash_map<K, V, I>(iter: I) -> HashMap<K, V>
28where
29    K: Eq + Hash,
30    I: Iterator<Item = (K, V)>,
31{
32    #[cfg(feature = "ahash")]
33    {
34        let mut map = HashMap::with_hasher(Hasher::with_seed(250402117));
35        map.extend(iter);
36        map
37    }
38    #[cfg(not(feature = "ahash"))]
39    iter.collect()
40}
41
42pub trait MutableExt<A> {
43    fn inspect(&self, f: impl FnOnce(&A));
44    fn inspect_mut(&self, f: impl FnOnce(&mut A));
45
46    fn map<B>(&self, f: impl FnOnce(&A) -> B) -> B;
47    fn map_mut<B>(&self, f: impl FnOnce(&mut A) -> B) -> B;
48
49    fn apply(&self, f: impl FnOnce(A) -> A)
50    where
51        A: Copy;
52    fn apply_cloned(&self, f: impl FnOnce(A) -> A)
53    where
54        A: Clone;
55
56    fn into_inner(self) -> A
57    where
58        A: Default,
59        Self: Sized,
60    {
61        self.map_mut(mem::take)
62    }
63
64    fn take(&self) -> A
65    where
66        A: Default,
67    {
68        self.map_mut(mem::take)
69    }
70}
71
72impl<A> MutableExt<A> for Mutable<A> {
73    fn inspect(&self, f: impl FnOnce(&A)) {
74        f(&self.lock_ref())
75    }
76
77    fn inspect_mut(&self, f: impl FnOnce(&mut A)) {
78        f(&mut self.lock_mut())
79    }
80
81    fn map<B>(&self, f: impl FnOnce(&A) -> B) -> B {
82        f(&self.lock_ref())
83    }
84
85    fn map_mut<B>(&self, f: impl FnOnce(&mut A) -> B) -> B {
86        f(&mut self.lock_mut())
87    }
88
89    fn apply(&self, f: impl FnOnce(A) -> A)
90    where
91        A: Copy,
92    {
93        self.set(f(self.get()))
94    }
95
96    fn apply_cloned(&self, f: impl FnOnce(A) -> A)
97    where
98        A: Clone,
99    {
100        self.set(f(self.get_cloned()))
101    }
102}
103
104pub trait MutableVecExt<A> {
105    fn map_vec<F, U>(&self, f: F) -> U
106    where
107        F: FnOnce(&[A]) -> U;
108
109    fn map_vec_mut<F, U>(&self, f: F) -> U
110    where
111        F: FnOnce(&mut MutableVecLockMut<A>) -> U;
112
113    fn inspect(&self, f: impl FnOnce(&[A]));
114    fn inspect_mut(&self, f: impl FnOnce(&mut MutableVecLockMut<A>));
115
116    fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
117    where
118        A: Copy,
119        P: FnMut(&A) -> bool,
120        F: FnOnce(&mut A) -> bool;
121
122    fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
123    where
124        A: Clone,
125        P: FnMut(&A) -> bool,
126        F: FnOnce(&mut A) -> bool;
127
128    fn map<F, U>(&self, f: F) -> Vec<U>
129    where
130        F: FnMut(&A) -> U;
131
132    fn enumerate_map<F, U>(&self, f: F) -> Vec<U>
133    where
134        F: FnMut(usize, &A) -> U;
135
136    fn filter<P>(&self, p: P) -> Vec<A>
137    where
138        A: Copy,
139        P: FnMut(&A) -> bool;
140
141    fn filter_cloned<P>(&self, p: P) -> Vec<A>
142    where
143        A: Clone,
144        P: FnMut(&A) -> bool;
145
146    fn filter_map<P, U>(&self, p: P) -> Vec<U>
147    where
148        P: FnMut(&A) -> Option<U>;
149
150    fn find<P>(&self, p: P) -> Option<A>
151    where
152        A: Copy,
153        P: FnMut(&A) -> bool;
154
155    fn find_cloned<P>(&self, p: P) -> Option<A>
156    where
157        A: Clone,
158        P: FnMut(&A) -> bool;
159
160    fn find_map<P, U>(&self, p: P) -> Option<U>
161    where
162        P: FnMut(&A) -> Option<U>;
163
164    fn find_set<P>(&self, p: P, item: A) -> bool
165    where
166        A: Copy,
167        P: FnMut(&A) -> bool;
168
169    fn find_set_cloned<P>(&self, p: P, item: A) -> bool
170    where
171        A: Clone,
172        P: FnMut(&A) -> bool;
173
174    fn find_set_or_add<P>(&self, p: P, item: A)
175    where
176        A: Copy,
177        P: FnMut(&A) -> bool;
178
179    fn find_set_or_add_cloned<P>(&self, p: P, item: A)
180    where
181        A: Clone,
182        P: FnMut(&A) -> bool;
183
184    fn find_remove<P>(&self, p: P) -> bool
185    where
186        A: Copy,
187        P: FnMut(&A) -> bool;
188
189    fn find_remove_cloned<P>(&self, p: P) -> bool
190    where
191        A: Clone,
192        P: FnMut(&A) -> bool;
193
194    fn extend(&self, source: impl IntoIterator<Item = A>)
195    where
196        A: Copy;
197
198    fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
199    where
200        A: Clone;
201
202    fn replace<P>(&self, what: P, with: impl IntoIterator<Item = A>)
203    where
204        A: Copy,
205        P: FnMut(&A) -> bool;
206
207    fn replace_cloned<P>(&self, what: P, with: impl IntoIterator<Item = A>)
208    where
209        A: Clone,
210        P: FnMut(&A) -> bool;
211
212    fn replace_keyed<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
213    where
214        A: Copy,
215        F: FnMut(&A) -> K,
216        K: Eq + Hash;
217
218    fn replace_keyed_cloned<F, K>(&self, f: F, source: impl IntoIterator<Item = A>) -> bool
219    where
220        A: Clone,
221        F: FnMut(&A) -> K,
222        K: Eq + Hash;
223
224    fn synchronize<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
225    where
226        A: Copy,
227        F: FnMut(&A) -> K,
228        K: Eq + Hash;
229
230    fn synchronize_cloned<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
231    where
232        A: Clone,
233        F: FnMut(&A) -> K,
234        K: Eq + Hash;
235
236    #[cfg(feature = "spawn")]
237    fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
238    where
239        A: Copy + Send + Sync + 'static;
240
241    #[cfg(feature = "spawn")]
242    fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
243    where
244        A: Clone + Send + Sync + 'static;
245
246    #[cfg(feature = "spawn-local")]
247    fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
248    where
249        A: Copy + 'static;
250
251    #[cfg(feature = "spawn-local")]
252    fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
253    where
254        A: Clone + 'static;
255
256    fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
257    where
258        A: Copy,
259        P: FnMut(&A) -> bool;
260
261    fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
262    where
263        A: Clone,
264        P: FnMut(&A) -> bool;
265
266    fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
267    where
268        A: Copy,
269        P: FnMut(&A) -> S,
270        S: Signal<Item = bool>;
271
272    fn signal_vec_filter_signal_cloned<P, S>(
273        &self,
274        p: P,
275    ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
276    where
277        A: Clone,
278        P: FnMut(&A) -> S,
279        S: Signal<Item = bool>;
280}
281
282impl<A> MutableVecExt<A> for MutableVec<A> {
283    fn map_vec<F, U>(&self, f: F) -> U
284    where
285        F: FnOnce(&[A]) -> U,
286    {
287        f(&self.lock_ref())
288    }
289
290    fn map_vec_mut<F, U>(&self, f: F) -> U
291    where
292        F: FnOnce(&mut MutableVecLockMut<A>) -> U,
293    {
294        f(&mut self.lock_mut())
295    }
296
297    fn inspect(&self, f: impl FnOnce(&[A])) {
298        f(&self.lock_ref())
299    }
300
301    fn inspect_mut(&self, f: impl FnOnce(&mut MutableVecLockMut<A>)) {
302        f(&mut self.lock_mut())
303    }
304
305    /// Return parameter of F (changed) drives if the value should be written back,
306    /// and cause MutableVec change. If F returns false, no change is induced neither
307    /// reported.
308    fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
309    where
310        A: Copy,
311        P: FnMut(&A) -> bool,
312        F: FnOnce(&mut A) -> bool,
313    {
314        self.entry(predicate)
315            .value()
316            .map(|mut value| value.inspect_mut(f))
317    }
318
319    /// Return parameter of F (changed) drives if the value should be written back,
320    /// and cause MutableVec change. If F returns false, no change is induced neither
321    /// reported.
322    fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
323    where
324        A: Clone,
325        P: FnMut(&A) -> bool,
326        F: FnOnce(&mut A) -> bool,
327    {
328        self.entry_cloned(predicate)
329            .value()
330            .map(|mut value| value.inspect_mut(f))
331    }
332
333    fn map<F, U>(&self, f: F) -> Vec<U>
334    where
335        F: FnMut(&A) -> U,
336    {
337        self.lock_ref().iter().map(f).collect()
338    }
339
340    fn enumerate_map<F, U>(&self, mut f: F) -> Vec<U>
341    where
342        F: FnMut(usize, &A) -> U,
343    {
344        self.lock_ref()
345            .iter()
346            .enumerate()
347            .map(|(index, item)| f(index, item))
348            .collect()
349    }
350
351    fn filter<P>(&self, mut p: P) -> Vec<A>
352    where
353        A: Copy,
354        P: FnMut(&A) -> bool,
355    {
356        self.lock_ref().iter().filter(|&a| p(a)).copied().collect()
357    }
358
359    fn filter_cloned<P>(&self, mut p: P) -> Vec<A>
360    where
361        A: Clone,
362        P: FnMut(&A) -> bool,
363    {
364        self.lock_ref().iter().filter(|&a| p(a)).cloned().collect()
365    }
366
367    fn filter_map<P, U>(&self, p: P) -> Vec<U>
368    where
369        P: FnMut(&A) -> Option<U>,
370    {
371        self.lock_ref().iter().filter_map(p).collect()
372    }
373
374    fn find<P>(&self, mut p: P) -> Option<A>
375    where
376        A: Copy,
377        P: FnMut(&A) -> bool,
378    {
379        self.lock_ref().iter().find(|&a| p(a)).copied()
380    }
381
382    fn find_cloned<P>(&self, mut p: P) -> Option<A>
383    where
384        A: Clone,
385        P: FnMut(&A) -> bool,
386    {
387        self.lock_ref().iter().find(|&a| p(a)).cloned()
388    }
389
390    fn find_map<P, U>(&self, p: P) -> Option<U>
391    where
392        P: FnMut(&A) -> Option<U>,
393    {
394        self.lock_ref().iter().find_map(p)
395    }
396
397    fn find_set<P>(&self, p: P, item: A) -> bool
398    where
399        A: Copy,
400        P: FnMut(&A) -> bool,
401    {
402        self.entry(p).and_set(item).is_occupied()
403    }
404
405    fn find_set_cloned<P>(&self, p: P, item: A) -> bool
406    where
407        A: Clone,
408        P: FnMut(&A) -> bool,
409    {
410        self.entry_cloned(p).and_set(item).is_occupied()
411    }
412
413    fn find_set_or_add<P>(&self, p: P, item: A)
414    where
415        A: Copy,
416        P: FnMut(&A) -> bool,
417    {
418        self.entry(p).or_insert_entry(item);
419    }
420
421    fn find_set_or_add_cloned<P>(&self, p: P, item: A)
422    where
423        A: Clone,
424        P: FnMut(&A) -> bool,
425    {
426        self.entry_cloned(p).or_insert_entry(item);
427    }
428
429    fn find_remove<P>(&self, p: P) -> bool
430    where
431        A: Copy,
432        P: FnMut(&A) -> bool,
433    {
434        self.entry(p).remove().is_some()
435    }
436
437    fn find_remove_cloned<P>(&self, p: P) -> bool
438    where
439        A: Clone,
440        P: FnMut(&A) -> bool,
441    {
442        self.entry_cloned(p).remove().is_some()
443    }
444
445    fn extend(&self, source: impl IntoIterator<Item = A>)
446    where
447        A: Copy,
448    {
449        let mut lock = self.lock_mut();
450        for item in source.into_iter() {
451            lock.push(item);
452        }
453    }
454
455    fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
456    where
457        A: Clone,
458    {
459        let mut lock = self.lock_mut();
460        for item in source.into_iter() {
461            lock.push_cloned(item);
462        }
463    }
464
465    fn replace<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
466    where
467        A: Copy,
468        P: FnMut(&A) -> bool,
469    {
470        let mut lock = self.lock_mut();
471        lock.retain(|item| !what(item));
472        for item in with.into_iter() {
473            lock.push(item);
474        }
475    }
476
477    fn replace_cloned<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
478    where
479        A: Clone,
480        P: FnMut(&A) -> bool,
481    {
482        let mut lock = self.lock_mut();
483        lock.retain(|item| !what(item));
484        for item in with.into_iter() {
485            lock.push_cloned(item);
486        }
487    }
488
489    fn replace_keyed<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
490    where
491        A: Copy,
492        F: FnMut(&A) -> K,
493        K: Eq + Hash,
494    {
495        let source = source.into_iter().map(|item| (key(&item), item));
496        let mut source = collect_hash_map(source);
497
498        let mut lock = self.lock_mut();
499
500        let to_replace = lock
501            .iter()
502            .enumerate()
503            .filter_map(|(index, item)| {
504                let key = key(item);
505                source.get(&key).map(|_| (index, key))
506            })
507            .collect::<Vec<_>>();
508        for (index, item) in to_replace
509            .into_iter()
510            .filter_map(|(index, key)| source.remove(&key).map(|item| (index, item)))
511        {
512            lock.set(index, item)
513        }
514
515        let extended = !source.is_empty();
516        for item in source.into_values() {
517            lock.push(item);
518        }
519
520        extended
521    }
522
523    fn replace_keyed_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
524    where
525        A: Clone,
526        F: FnMut(&A) -> K,
527        K: Eq + Hash,
528    {
529        let source = source.into_iter().map(|item| (key(&item), item));
530        let mut source = collect_hash_map(source);
531
532        let mut lock = self.lock_mut();
533
534        let to_replace = lock
535            .iter()
536            .enumerate()
537            .filter_map(|(index, item)| {
538                let key = key(item);
539                source.get(&key).map(|_| (index, key))
540            })
541            .collect::<Vec<_>>();
542        for (index, item) in to_replace
543            .into_iter()
544            .filter_map(|(index, key)| source.remove(&key).map(|item| (index, item)))
545        {
546            lock.set_cloned(index, item)
547        }
548
549        let extended = !source.is_empty();
550        for item in source.into_values() {
551            lock.push_cloned(item);
552        }
553
554        extended
555    }
556
557    fn synchronize<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
558    where
559        A: Copy,
560        F: FnMut(&A) -> K,
561        K: Eq + Hash,
562    {
563        let source = source.into_iter().map(|item| (key(&item), item));
564        let mut source = collect_hash_map(source);
565
566        let mut lock = self.lock_mut();
567
568        let to_remove: Vec<_> = lock
569            .iter()
570            .enumerate()
571            .rev()
572            .filter_map(|(index, item)| match source.remove(&key(item)) {
573                Some(_) => None,
574                None => Some(index),
575            })
576            .collect();
577        // indexes go down, no need to calculate them anyhow
578        for index in to_remove.into_iter() {
579            lock.remove(index);
580        }
581
582        let extended = !source.is_empty();
583        for item in source.into_values() {
584            lock.push(item);
585        }
586
587        extended
588    }
589
590    fn synchronize_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
591    where
592        A: Clone,
593        F: FnMut(&A) -> K,
594        K: Eq + Hash,
595    {
596        let source = source.into_iter().map(|item| (key(&item), item));
597        let mut source = collect_hash_map(source);
598
599        let mut lock = self.lock_mut();
600
601        let to_remove = lock
602            .iter()
603            .enumerate()
604            .rev()
605            .filter_map(|(index, item)| match source.remove(&key(item)) {
606                Some(_) => None,
607                None => Some(index),
608            })
609            .collect::<Vec<_>>();
610        // indexes go down, no need to calculate them anyhow
611        for index in to_remove.into_iter() {
612            lock.remove(index);
613        }
614
615        let extended = !source.is_empty();
616        for item in source.into_values() {
617            lock.push_cloned(item);
618        }
619
620        extended
621    }
622
623    #[cfg(feature = "spawn")]
624    fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
625    where
626        A: Copy + Send + Sync + 'static,
627    {
628        source.feed(self.clone());
629    }
630
631    #[cfg(feature = "spawn")]
632    fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
633    where
634        A: Clone + Send + Sync + 'static,
635    {
636        source.feed_cloned(self.clone());
637    }
638
639    #[cfg(feature = "spawn-local")]
640    fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
641    where
642        A: Copy + 'static,
643    {
644        source.feed_local(self.clone());
645    }
646
647    #[cfg(feature = "spawn-local")]
648    fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
649    where
650        A: Clone + 'static,
651    {
652        source.feed_local_cloned(self.clone());
653    }
654
655    fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
656    where
657        A: Copy,
658        P: FnMut(&A) -> bool,
659    {
660        self.signal_vec().filter(p)
661    }
662
663    fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
664    where
665        A: Clone,
666        P: FnMut(&A) -> bool,
667    {
668        self.signal_vec_cloned().filter(p)
669    }
670
671    fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
672    where
673        A: Copy,
674        P: FnMut(&A) -> S,
675        S: Signal<Item = bool>,
676    {
677        self.signal_vec().filter_signal_cloned(p)
678    }
679
680    fn signal_vec_filter_signal_cloned<P, S>(
681        &self,
682        p: P,
683    ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
684    where
685        A: Clone,
686        P: FnMut(&A) -> S,
687        S: Signal<Item = bool>,
688    {
689        self.signal_vec_cloned().filter_signal_cloned(p)
690    }
691}
692
693pub trait SignalVecFinalizerExt: SignalVec + Sized {
694    fn first(self) -> impl Signal<Item = Option<Self::Item>>
695    where
696        Self::Item: Copy,
697    {
698        self.first_map(|i| *i)
699    }
700
701    fn first_cloned(self) -> impl Signal<Item = Option<Self::Item>>
702    where
703        Self::Item: Clone,
704    {
705        self.first_map(|i| i.clone())
706    }
707
708    fn first_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
709    where
710        F: FnMut(&Self::Item) -> U,
711    {
712        self.to_signal_map(move |items| items.first().map(&mut f))
713    }
714
715    fn last(self) -> impl Signal<Item = Option<Self::Item>>
716    where
717        Self::Item: Copy,
718    {
719        self.last_map(|i| *i)
720    }
721
722    fn last_cloned(self) -> impl Signal<Item = Option<Self::Item>>
723    where
724        Self::Item: Clone,
725    {
726        self.last_map(|i| i.clone())
727    }
728
729    fn last_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
730    where
731        F: FnMut(&Self::Item) -> U,
732    {
733        self.to_signal_map(move |items| items.last().map(&mut f))
734    }
735
736    fn all<F>(self, mut f: F) -> impl Signal<Item = bool>
737    where
738        F: FnMut(&Self::Item) -> bool,
739    {
740        self.to_signal_map(move |items| items.iter().all(&mut f))
741    }
742
743    fn any<F>(self, mut f: F) -> impl Signal<Item = bool>
744    where
745        F: FnMut(&Self::Item) -> bool,
746    {
747        self.to_signal_map(move |items| items.iter().any(&mut f))
748    }
749
750    fn seq(self) -> Sequence<Self> {
751        Sequence {
752            signal: self,
753            sequence: 0,
754        }
755    }
756}
757
758impl<S: SignalVec + Sized> SignalVecFinalizerExt for S {}
759
760pub trait SignalVecFlattenExt: SignalVec + Sized {
761    fn flatten_ext(self) -> Flatten<Self>
762    where
763        Self::Item: SignalVec,
764    {
765        Flatten {
766            signal: Some(self),
767            inner: vec![],
768            pending: VecDeque::new(),
769        }
770    }
771}
772
773impl<S: SignalVec + Sized> SignalVecFlattenExt for S {}
774
775pub trait SignalExtMapBool
776where
777    Self: Sized,
778{
779    fn map_bool<T, TM: FnMut() -> T, FM: FnMut() -> T>(
780        self,
781        t: TM,
782        f: FM,
783    ) -> MapBool<Self, TM, FM> {
784        MapBool {
785            signal: self,
786            true_mapper: t,
787            false_mapper: f,
788        }
789    }
790
791    fn map_option<T, TM: FnMut() -> T>(self, t: TM) -> MapOption<Self, TM> {
792        MapOption {
793            signal: self,
794            true_mapper: t,
795        }
796    }
797}
798
799impl<S: Signal<Item = bool> + Sized> SignalExtMapBool for S {}
800
801pin_project! {
802    #[derive(Debug)]
803    #[must_use = "Signals do nothing unless polled"]
804    pub struct MapBool<S, TM, FM> {
805        #[pin]
806        signal: S,
807        true_mapper: TM,
808        false_mapper: FM,
809    }
810}
811
812impl<T, S: Signal<Item = bool>, TM: FnMut() -> T, FM: FnMut() -> T> Signal for MapBool<S, TM, FM> {
813    type Item = T;
814
815    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
816        let this = self.project();
817
818        this.signal.poll_change(cx).map(|opt| {
819            opt.map(|value| {
820                if value {
821                    (this.true_mapper)()
822                } else {
823                    (this.false_mapper)()
824                }
825            })
826        })
827    }
828}
829
830pin_project! {
831    #[derive(Debug)]
832    #[must_use = "Signals do nothing unless polled"]
833    pub struct MapOption<S, TM> {
834        #[pin]
835        signal: S,
836        true_mapper: TM,
837    }
838}
839
840impl<T, S: Signal<Item = bool>, TM: FnMut() -> T> Signal for MapOption<S, TM> {
841    type Item = Option<T>;
842
843    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
844        let this = self.project();
845
846        this.signal
847            .poll_change(cx)
848            .map(|opt| opt.map(|value| value.then(this.true_mapper)))
849    }
850}
851
852pub trait SignalExtMapOption<T>
853where
854    Self: Sized,
855{
856    fn map_some<F, U>(self, f: F) -> MapSome<Self, T, F, U>
857    where
858        F: FnMut(&T) -> U,
859    {
860        MapSome {
861            signal: self,
862            mapper: f,
863            pt: PhantomData,
864            pu: PhantomData,
865        }
866    }
867
868    fn map_some_default<F, U>(self, f: F) -> MapSomeDefault<Self, T, F, U>
869    where
870        F: FnMut(&T) -> U,
871        U: Default,
872    {
873        MapSomeDefault {
874            signal: self,
875            mapper: f,
876            pt: PhantomData,
877            pu: PhantomData,
878        }
879    }
880
881    fn and_then_some<F, U>(self, f: F) -> AndThenSome<Self, T, F, U>
882    where
883        F: FnMut(&T) -> Option<U>,
884    {
885        AndThenSome {
886            signal: self,
887            mapper: f,
888            pt: PhantomData,
889            pu: PhantomData,
890        }
891    }
892
893    fn unwrap_or_default(self) -> UnwrapOrDefault<Self, T>
894    where
895        T: Default,
896    {
897        UnwrapOrDefault {
898            signal: self,
899            pt: PhantomData,
900        }
901    }
902}
903
904impl<T, S: Signal<Item = Option<T>> + Sized> SignalExtMapOption<T> for S {}
905
906pin_project! {
907    #[derive(Debug)]
908    #[must_use = "Signals do nothing unless polled"]
909    pub struct MapSome<S, T, F, U> {
910        #[pin]
911        signal: S,
912        mapper: F,
913        pt: PhantomData<T>,
914        pu: PhantomData<U>,
915    }
916}
917
918impl<T, S, F, U> Signal for MapSome<S, T, F, U>
919where
920    S: Signal<Item = Option<T>>,
921    F: FnMut(&T) -> U,
922{
923    type Item = Option<U>;
924
925    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
926        let this = self.project();
927        this.signal
928            .poll_change(cx)
929            .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value))))
930    }
931}
932
933pin_project! {
934    #[derive(Debug)]
935    #[must_use = "Signals do nothing unless polled"]
936    pub struct MapSomeDefault<S, T, F, U> {
937        #[pin]
938        signal: S,
939        mapper: F,
940        pt: PhantomData<T>,
941        pu: PhantomData<U>,
942    }
943}
944
945impl<T, S, F, U> Signal for MapSomeDefault<S, T, F, U>
946where
947    S: Signal<Item = Option<T>>,
948    F: FnMut(&T) -> U,
949    U: Default,
950{
951    type Item = U;
952
953    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
954        let this = self.project();
955        this.signal
956            .poll_change(cx)
957            .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value)).unwrap_or_default()))
958    }
959}
960
961pin_project! {
962    #[derive(Debug)]
963    #[must_use = "Signals do nothing unless polled"]
964    pub struct AndThenSome<S, T, F, U> {
965        #[pin]
966        signal: S,
967        mapper: F,
968        pt: PhantomData<T>,
969        pu: PhantomData<U>,
970    }
971}
972
973impl<T, S, F, U> Signal for AndThenSome<S, T, F, U>
974where
975    S: Signal<Item = Option<T>>,
976    F: FnMut(&T) -> Option<U>,
977{
978    type Item = Option<U>;
979
980    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
981        let this = self.project();
982        this.signal
983            .poll_change(cx)
984            .map(|opt| opt.map(|opt| opt.and_then(|value| (this.mapper)(&value))))
985    }
986}
987
988pin_project! {
989    #[derive(Debug)]
990    #[must_use = "Signals do nothing unless polled"]
991    pub struct UnwrapOrDefault<S, T> {
992        #[pin]
993        signal: S,
994        pt: PhantomData<T>,
995    }
996}
997
998impl<T, S> Signal for UnwrapOrDefault<S, T>
999where
1000    S: Signal<Item = Option<T>>,
1001    T: Default,
1002{
1003    type Item = T;
1004
1005    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1006        self.project()
1007            .signal
1008            .poll_change(cx)
1009            .map(|opt| opt.map(|opt| opt.unwrap_or_default()))
1010    }
1011}
1012
1013pin_project! {
1014    #[derive(Debug)]
1015    #[must_use = "Signals do nothing unless polled"]
1016    pub struct Sequence<A>
1017    where
1018        A: SignalVec,
1019    {
1020        #[pin]
1021        signal: A,
1022        sequence: u64,
1023    }
1024}
1025
1026impl<A> Signal for Sequence<A>
1027where
1028    A: SignalVec,
1029{
1030    type Item = u64;
1031
1032    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1033        let mut this = self.project();
1034
1035        let mut changed = false;
1036
1037        let done = loop {
1038            break match this.signal.as_mut().poll_vec_change(cx) {
1039                Poll::Ready(None) => true,
1040                Poll::Ready(Some(_)) => {
1041                    *this.sequence += 1;
1042                    changed = true;
1043                    continue;
1044                }
1045                Poll::Pending => false,
1046            };
1047        };
1048
1049        if changed {
1050            Poll::Ready(Some(*this.sequence))
1051        } else if done {
1052            Poll::Ready(None)
1053        } else {
1054            Poll::Pending
1055        }
1056    }
1057}