Skip to main content

futures_signals_ext/
ext.rs

1use futures_signals::{
2    signal::{Mutable, Signal, SignalExt},
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_vec(&self, f: impl FnMut(&[A]));
114    fn inspect_vec_mut(&self, f: impl FnMut(&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    #[inline]
298    fn inspect_vec(&self, mut f: impl FnMut(&[A])) {
299        f(&self.lock_ref())
300    }
301
302    #[inline]
303    fn inspect_vec_mut(&self, mut f: impl FnMut(&mut MutableVecLockMut<A>)) {
304        f(&mut self.lock_mut())
305    }
306
307    /// Return parameter of F (changed) drives if the value should be written back,
308    /// and cause MutableVec change. If F returns false, no change is induced neither
309    /// reported.
310    fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
311    where
312        A: Copy,
313        P: FnMut(&A) -> bool,
314        F: FnOnce(&mut A) -> bool,
315    {
316        self.entry(predicate)
317            .value()
318            .map(|mut value| value.inspect_mut(f))
319    }
320
321    /// Return parameter of F (changed) drives if the value should be written back,
322    /// and cause MutableVec change. If F returns false, no change is induced neither
323    /// reported.
324    fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
325    where
326        A: Clone,
327        P: FnMut(&A) -> bool,
328        F: FnOnce(&mut A) -> bool,
329    {
330        self.entry_cloned(predicate)
331            .value()
332            .map(|mut value| value.inspect_mut(f))
333    }
334
335    fn map<F, U>(&self, f: F) -> Vec<U>
336    where
337        F: FnMut(&A) -> U,
338    {
339        self.lock_ref().iter().map(f).collect()
340    }
341
342    fn enumerate_map<F, U>(&self, mut f: F) -> Vec<U>
343    where
344        F: FnMut(usize, &A) -> U,
345    {
346        self.lock_ref()
347            .iter()
348            .enumerate()
349            .map(|(index, item)| f(index, item))
350            .collect()
351    }
352
353    fn filter<P>(&self, mut p: P) -> Vec<A>
354    where
355        A: Copy,
356        P: FnMut(&A) -> bool,
357    {
358        self.lock_ref().iter().filter(|&a| p(a)).copied().collect()
359    }
360
361    fn filter_cloned<P>(&self, mut p: P) -> Vec<A>
362    where
363        A: Clone,
364        P: FnMut(&A) -> bool,
365    {
366        self.lock_ref().iter().filter(|&a| p(a)).cloned().collect()
367    }
368
369    fn filter_map<P, U>(&self, p: P) -> Vec<U>
370    where
371        P: FnMut(&A) -> Option<U>,
372    {
373        self.lock_ref().iter().filter_map(p).collect()
374    }
375
376    fn find<P>(&self, mut p: P) -> Option<A>
377    where
378        A: Copy,
379        P: FnMut(&A) -> bool,
380    {
381        self.lock_ref().iter().find(|&a| p(a)).copied()
382    }
383
384    fn find_cloned<P>(&self, mut p: P) -> Option<A>
385    where
386        A: Clone,
387        P: FnMut(&A) -> bool,
388    {
389        self.lock_ref().iter().find(|&a| p(a)).cloned()
390    }
391
392    fn find_map<P, U>(&self, p: P) -> Option<U>
393    where
394        P: FnMut(&A) -> Option<U>,
395    {
396        self.lock_ref().iter().find_map(p)
397    }
398
399    fn find_set<P>(&self, p: P, item: A) -> bool
400    where
401        A: Copy,
402        P: FnMut(&A) -> bool,
403    {
404        self.entry(p).and_set(item).is_occupied()
405    }
406
407    fn find_set_cloned<P>(&self, p: P, item: A) -> bool
408    where
409        A: Clone,
410        P: FnMut(&A) -> bool,
411    {
412        self.entry_cloned(p).and_set(item).is_occupied()
413    }
414
415    fn find_set_or_add<P>(&self, p: P, item: A)
416    where
417        A: Copy,
418        P: FnMut(&A) -> bool,
419    {
420        self.entry(p).and_set_or_insert(item);
421    }
422
423    fn find_set_or_add_cloned<P>(&self, p: P, item: A)
424    where
425        A: Clone,
426        P: FnMut(&A) -> bool,
427    {
428        self.entry_cloned(p).and_set_or_insert(item);
429    }
430
431    fn find_remove<P>(&self, p: P) -> bool
432    where
433        A: Copy,
434        P: FnMut(&A) -> bool,
435    {
436        self.entry(p).remove().is_some()
437    }
438
439    fn find_remove_cloned<P>(&self, p: P) -> bool
440    where
441        A: Clone,
442        P: FnMut(&A) -> bool,
443    {
444        self.entry_cloned(p).remove().is_some()
445    }
446
447    fn extend(&self, source: impl IntoIterator<Item = A>)
448    where
449        A: Copy,
450    {
451        let mut lock = self.lock_mut();
452        for item in source.into_iter() {
453            lock.push(item);
454        }
455    }
456
457    fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
458    where
459        A: Clone,
460    {
461        let mut lock = self.lock_mut();
462        for item in source.into_iter() {
463            lock.push_cloned(item);
464        }
465    }
466
467    fn replace<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
468    where
469        A: Copy,
470        P: FnMut(&A) -> bool,
471    {
472        let mut lock = self.lock_mut();
473        lock.retain(|item| !what(item));
474        for item in with.into_iter() {
475            lock.push(item);
476        }
477    }
478
479    fn replace_cloned<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
480    where
481        A: Clone,
482        P: FnMut(&A) -> bool,
483    {
484        let mut lock = self.lock_mut();
485        lock.retain(|item| !what(item));
486        for item in with.into_iter() {
487            lock.push_cloned(item);
488        }
489    }
490
491    fn replace_keyed<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
492    where
493        A: Copy,
494        F: FnMut(&A) -> K,
495        K: Eq + Hash,
496    {
497        let source = source.into_iter().map(|item| (key(&item), item));
498        let mut source = collect_hash_map(source);
499
500        let mut lock = self.lock_mut();
501
502        let to_replace = lock
503            .iter()
504            .enumerate()
505            .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
506            .collect::<Vec<_>>();
507        for (index, item) in to_replace {
508            lock.set(index, item)
509        }
510
511        let extended = !source.is_empty();
512        for item in source.into_values() {
513            lock.push(item);
514        }
515
516        extended
517    }
518
519    fn replace_keyed_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
520    where
521        A: Clone,
522        F: FnMut(&A) -> K,
523        K: Eq + Hash,
524    {
525        let source = source.into_iter().map(|item| (key(&item), item));
526        let mut source = collect_hash_map(source);
527
528        let mut lock = self.lock_mut();
529
530        let to_replace = lock
531            .iter()
532            .enumerate()
533            .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
534            .collect::<Vec<_>>();
535        for (index, item) in to_replace {
536            lock.set_cloned(index, item)
537        }
538
539        let extended = !source.is_empty();
540        for item in source.into_values() {
541            lock.push_cloned(item);
542        }
543
544        extended
545    }
546
547    fn synchronize<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
548    where
549        A: Copy,
550        F: FnMut(&A) -> K,
551        K: Eq + Hash,
552    {
553        let source = source.into_iter().map(|item| (key(&item), item));
554        let mut source = collect_hash_map(source);
555
556        let mut lock = self.lock_mut();
557
558        let to_remove: Vec<_> = lock
559            .iter()
560            .enumerate()
561            .rev()
562            .filter_map(|(index, item)| match source.remove(&key(item)) {
563                Some(_) => None,
564                None => Some(index),
565            })
566            .collect();
567        // indexes go down, no need to calculate them anyhow
568        for index in to_remove.into_iter() {
569            lock.remove(index);
570        }
571
572        let extended = !source.is_empty();
573        for item in source.into_values() {
574            lock.push(item);
575        }
576
577        extended
578    }
579
580    fn synchronize_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
581    where
582        A: Clone,
583        F: FnMut(&A) -> K,
584        K: Eq + Hash,
585    {
586        let source = source.into_iter().map(|item| (key(&item), item));
587        let mut source = collect_hash_map(source);
588
589        let mut lock = self.lock_mut();
590
591        let to_remove = lock
592            .iter()
593            .enumerate()
594            .rev()
595            .filter_map(|(index, item)| match source.remove(&key(item)) {
596                Some(_) => None,
597                None => Some(index),
598            })
599            .collect::<Vec<_>>();
600        // indexes go down, no need to calculate them anyhow
601        for index in to_remove.into_iter() {
602            lock.remove(index);
603        }
604
605        let extended = !source.is_empty();
606        for item in source.into_values() {
607            lock.push_cloned(item);
608        }
609
610        extended
611    }
612
613    #[cfg(feature = "spawn")]
614    fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
615    where
616        A: Copy + Send + Sync + 'static,
617    {
618        source.feed(self.clone());
619    }
620
621    #[cfg(feature = "spawn")]
622    fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
623    where
624        A: Clone + Send + Sync + 'static,
625    {
626        source.feed_cloned(self.clone());
627    }
628
629    #[cfg(feature = "spawn-local")]
630    fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
631    where
632        A: Copy + 'static,
633    {
634        source.feed_local(self.clone());
635    }
636
637    #[cfg(feature = "spawn-local")]
638    fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
639    where
640        A: Clone + 'static,
641    {
642        source.feed_local_cloned(self.clone());
643    }
644
645    fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
646    where
647        A: Copy,
648        P: FnMut(&A) -> bool,
649    {
650        self.signal_vec().filter(p)
651    }
652
653    fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
654    where
655        A: Clone,
656        P: FnMut(&A) -> bool,
657    {
658        self.signal_vec_cloned().filter(p)
659    }
660
661    fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
662    where
663        A: Copy,
664        P: FnMut(&A) -> S,
665        S: Signal<Item = bool>,
666    {
667        self.signal_vec().filter_signal_cloned(p)
668    }
669
670    fn signal_vec_filter_signal_cloned<P, S>(
671        &self,
672        p: P,
673    ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
674    where
675        A: Clone,
676        P: FnMut(&A) -> S,
677        S: Signal<Item = bool>,
678    {
679        self.signal_vec_cloned().filter_signal_cloned(p)
680    }
681}
682
683pub trait SignalVecFinalizerExt: SignalVec + Sized {
684    #[inline]
685    fn first(self) -> impl Signal<Item = Option<Self::Item>>
686    where
687        Self::Item: Copy,
688    {
689        self.first_map(|i| *i)
690    }
691
692    fn first_cloned(self) -> impl Signal<Item = Option<Self::Item>>
693    where
694        Self::Item: Clone,
695    {
696        self.first_map(|i| i.clone())
697    }
698
699    fn first_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
700    where
701        F: FnMut(&Self::Item) -> U,
702    {
703        self.to_signal_map(move |items| items.first().map(&mut f))
704    }
705
706    #[inline]
707    fn last(self) -> impl Signal<Item = Option<Self::Item>>
708    where
709        Self::Item: Copy,
710    {
711        self.last_map(|i| *i)
712    }
713
714    fn last_cloned(self) -> impl Signal<Item = Option<Self::Item>>
715    where
716        Self::Item: Clone,
717    {
718        self.last_map(|i| i.clone())
719    }
720
721    fn last_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
722    where
723        F: FnMut(&Self::Item) -> U,
724    {
725        self.to_signal_map(move |items| items.last().map(&mut f))
726    }
727
728    fn all<F>(self, mut f: F) -> impl Signal<Item = bool>
729    where
730        F: FnMut(&Self::Item) -> bool,
731    {
732        self.to_signal_map(move |items| items.iter().all(&mut f))
733    }
734
735    fn any<F>(self, mut f: F) -> impl Signal<Item = bool>
736    where
737        F: FnMut(&Self::Item) -> bool,
738    {
739        self.to_signal_map(move |items| items.iter().any(&mut f))
740    }
741
742    #[inline]
743    fn any_item(self) -> impl Signal<Item = bool> {
744        self.len().neq(0)
745    }
746
747    fn seq(self) -> Sequence<Self> {
748        Sequence {
749            signal: self,
750            sequence: 0,
751        }
752    }
753}
754
755impl<S: SignalVec + Sized> SignalVecFinalizerExt for S {}
756
757pub trait SignalVecFlattenExt: SignalVec + Sized {
758    fn flatten_ext(self) -> Flatten<Self>
759    where
760        Self::Item: SignalVec,
761    {
762        Flatten {
763            signal: Some(self),
764            inner: vec![],
765            pending: VecDeque::new(),
766        }
767    }
768}
769
770impl<S: SignalVec + Sized> SignalVecFlattenExt for S {}
771
772pub trait SignalExtMapBool
773where
774    Self: Sized,
775{
776    fn map_bool<T, TM: FnMut() -> T, FM: FnMut() -> T>(
777        self,
778        t: TM,
779        f: FM,
780    ) -> MapBool<Self, TM, FM> {
781        MapBool {
782            signal: self,
783            true_mapper: t,
784            false_mapper: f,
785        }
786    }
787
788    fn map_option<T, TM: FnMut() -> T>(self, t: TM) -> MapOption<Self, TM> {
789        MapOption {
790            signal: self,
791            true_mapper: t,
792        }
793    }
794}
795
796impl<S: Signal<Item = bool> + Sized> SignalExtMapBool for S {}
797
798pin_project! {
799    #[derive(Debug)]
800    #[must_use = "Signals do nothing unless polled"]
801    pub struct MapBool<S, TM, FM> {
802        #[pin]
803        signal: S,
804        true_mapper: TM,
805        false_mapper: FM,
806    }
807}
808
809impl<T, S: Signal<Item = bool>, TM: FnMut() -> T, FM: FnMut() -> T> Signal for MapBool<S, TM, FM> {
810    type Item = T;
811
812    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
813        let this = self.project();
814
815        this.signal.poll_change(cx).map(|opt| {
816            opt.map(|value| {
817                if value {
818                    (this.true_mapper)()
819                } else {
820                    (this.false_mapper)()
821                }
822            })
823        })
824    }
825}
826
827pin_project! {
828    #[derive(Debug)]
829    #[must_use = "Signals do nothing unless polled"]
830    pub struct MapOption<S, TM> {
831        #[pin]
832        signal: S,
833        true_mapper: TM,
834    }
835}
836
837impl<T, S: Signal<Item = bool>, TM: FnMut() -> T> Signal for MapOption<S, TM> {
838    type Item = Option<T>;
839
840    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
841        let this = self.project();
842
843        this.signal
844            .poll_change(cx)
845            .map(|opt| opt.map(|value| value.then(this.true_mapper)))
846    }
847}
848
849pub trait SignalExtMapOption<T>
850where
851    Self: Sized,
852{
853    fn map_some<F, U>(self, f: F) -> MapSome<Self, T, F, U>
854    where
855        F: FnMut(&T) -> U,
856    {
857        MapSome {
858            signal: self,
859            mapper: f,
860            pt: PhantomData,
861            pu: PhantomData,
862        }
863    }
864
865    fn map_some_default<F, U>(self, f: F) -> MapSomeDefault<Self, T, F, U>
866    where
867        F: FnMut(&T) -> U,
868        U: Default,
869    {
870        MapSomeDefault {
871            signal: self,
872            mapper: f,
873            pt: PhantomData,
874            pu: PhantomData,
875        }
876    }
877
878    fn and_then_some<F, U>(self, f: F) -> AndThenSome<Self, T, F, U>
879    where
880        F: FnMut(&T) -> Option<U>,
881    {
882        AndThenSome {
883            signal: self,
884            mapper: f,
885            pt: PhantomData,
886            pu: PhantomData,
887        }
888    }
889
890    fn unwrap_or_default(self) -> UnwrapOrDefault<Self, T>
891    where
892        T: Default,
893    {
894        UnwrapOrDefault {
895            signal: self,
896            pt: PhantomData,
897        }
898    }
899}
900
901impl<T, S: Signal<Item = Option<T>> + Sized> SignalExtMapOption<T> for S {}
902
903pin_project! {
904    #[derive(Debug)]
905    #[must_use = "Signals do nothing unless polled"]
906    pub struct MapSome<S, T, F, U> {
907        #[pin]
908        signal: S,
909        mapper: F,
910        pt: PhantomData<T>,
911        pu: PhantomData<U>,
912    }
913}
914
915impl<T, S, F, U> Signal for MapSome<S, T, F, U>
916where
917    S: Signal<Item = Option<T>>,
918    F: FnMut(&T) -> U,
919{
920    type Item = Option<U>;
921
922    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
923        let this = self.project();
924        this.signal
925            .poll_change(cx)
926            .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value))))
927    }
928}
929
930pin_project! {
931    #[derive(Debug)]
932    #[must_use = "Signals do nothing unless polled"]
933    pub struct MapSomeDefault<S, T, F, U> {
934        #[pin]
935        signal: S,
936        mapper: F,
937        pt: PhantomData<T>,
938        pu: PhantomData<U>,
939    }
940}
941
942impl<T, S, F, U> Signal for MapSomeDefault<S, T, F, U>
943where
944    S: Signal<Item = Option<T>>,
945    F: FnMut(&T) -> U,
946    U: Default,
947{
948    type Item = U;
949
950    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
951        let this = self.project();
952        this.signal
953            .poll_change(cx)
954            .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value)).unwrap_or_default()))
955    }
956}
957
958pin_project! {
959    #[derive(Debug)]
960    #[must_use = "Signals do nothing unless polled"]
961    pub struct AndThenSome<S, T, F, U> {
962        #[pin]
963        signal: S,
964        mapper: F,
965        pt: PhantomData<T>,
966        pu: PhantomData<U>,
967    }
968}
969
970impl<T, S, F, U> Signal for AndThenSome<S, T, F, U>
971where
972    S: Signal<Item = Option<T>>,
973    F: FnMut(&T) -> Option<U>,
974{
975    type Item = Option<U>;
976
977    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
978        let this = self.project();
979        this.signal
980            .poll_change(cx)
981            .map(|opt| opt.map(|opt| opt.and_then(|value| (this.mapper)(&value))))
982    }
983}
984
985pin_project! {
986    #[derive(Debug)]
987    #[must_use = "Signals do nothing unless polled"]
988    pub struct UnwrapOrDefault<S, T> {
989        #[pin]
990        signal: S,
991        pt: PhantomData<T>,
992    }
993}
994
995impl<T, S> Signal for UnwrapOrDefault<S, T>
996where
997    S: Signal<Item = Option<T>>,
998    T: Default,
999{
1000    type Item = T;
1001
1002    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1003        self.project()
1004            .signal
1005            .poll_change(cx)
1006            .map(|opt| opt.map(|opt| opt.unwrap_or_default()))
1007    }
1008}
1009
1010pin_project! {
1011    #[derive(Debug)]
1012    #[must_use = "Signals do nothing unless polled"]
1013    pub struct Sequence<A>
1014    where
1015        A: SignalVec,
1016    {
1017        #[pin]
1018        signal: A,
1019        sequence: u64,
1020    }
1021}
1022
1023impl<A> Signal for Sequence<A>
1024where
1025    A: SignalVec,
1026{
1027    type Item = u64;
1028
1029    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1030        let mut this = self.project();
1031
1032        let mut changed = false;
1033
1034        let done = loop {
1035            break match this.signal.as_mut().poll_vec_change(cx) {
1036                Poll::Ready(None) => true,
1037                Poll::Ready(Some(_)) => {
1038                    *this.sequence += 1;
1039                    changed = true;
1040                    continue;
1041                }
1042                Poll::Pending => false,
1043            };
1044        };
1045
1046        if changed {
1047            Poll::Ready(Some(*this.sequence))
1048        } else if done {
1049            Poll::Ready(None)
1050        } else {
1051            Poll::Pending
1052        }
1053    }
1054}
1055
1056#[cfg(test)]
1057mod test {
1058    use futures_signals::signal_vec::MutableVec;
1059
1060    use crate::MutableVecExt;
1061
1062    #[test]
1063    fn replace_keyed() {
1064        let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1065        assert_eq!(vec.replace_keyed(|(k, _)| *k, [("b", 20), ("d", 4)]), true);
1066        assert_eq!(
1067            vec.lock_ref().as_slice(),
1068            &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1069        );
1070    }
1071
1072    #[test]
1073    fn replace_keyed_cloned() {
1074        let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1075        assert_eq!(
1076            vec.replace_keyed_cloned(|(k, _)| *k, [("b", 20), ("d", 4)]),
1077            true
1078        );
1079        assert_eq!(
1080            vec.lock_ref().as_slice(),
1081            &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1082        );
1083    }
1084}