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