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