Skip to main content

futures_signals_ext/
ext.rs

1use futures_signals::{
2    signal::{Mutable, Signal, SignalExt},
3    signal_vec::{
4        Filter, FilterMap, FilterSignalCloned, MutableSignalVec, MutableVec, MutableVecLockMut,
5        SignalVec, 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 into_inner(self) -> A
50    where
51        A: Default,
52        Self: Sized,
53    {
54        self.map_mut(mem::take)
55    }
56
57    fn take(&self) -> A
58    where
59        A: Default,
60    {
61        self.map_mut(mem::take)
62    }
63}
64
65impl<A> MutableExt<A> for Mutable<A> {
66    fn inspect(&self, mut f: impl FnMut(&A)) {
67        f(&self.lock_ref())
68    }
69
70    fn inspect_mut(&self, mut f: impl FnMut(&mut A)) {
71        f(&mut self.lock_mut())
72    }
73
74    fn map<B>(&self, f: impl FnOnce(&A) -> B) -> B {
75        f(&self.lock_ref())
76    }
77
78    fn map_mut<B>(&self, f: impl FnOnce(&mut A) -> B) -> B {
79        f(&mut self.lock_mut())
80    }
81}
82
83pub trait MutableVecExt<A> {
84    fn inspect_vec(&self, f: impl FnMut(&[A]));
85    fn inspect_vec_mut(&self, f: impl FnMut(&mut MutableVecLockMut<A>));
86
87    fn map_vec<F, U>(&self, f: F) -> U
88    where
89        F: FnOnce(&[A]) -> U;
90
91    fn map_vec_mut<F, U>(&self, f: F) -> U
92    where
93        F: FnOnce(&mut MutableVecLockMut<A>) -> U;
94
95    fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
96    where
97        A: Copy,
98        P: FnMut(&A) -> bool,
99        F: FnMut(&mut A) -> bool;
100
101    fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
102    where
103        A: Clone,
104        P: FnMut(&A) -> bool,
105        F: FnMut(&mut A) -> bool;
106
107    fn map<F, U>(&self, f: F) -> Vec<U>
108    where
109        F: FnMut(&A) -> U;
110
111    fn enumerate_map<F, U>(&self, f: F) -> Vec<U>
112    where
113        F: FnMut(usize, &A) -> U;
114
115    fn filter<P>(&self, p: P) -> Vec<A>
116    where
117        A: Copy,
118        P: FnMut(&A) -> bool;
119
120    fn filter_cloned<P>(&self, p: P) -> Vec<A>
121    where
122        A: Clone,
123        P: FnMut(&A) -> bool;
124
125    fn filter_map<P, U>(&self, p: P) -> Vec<U>
126    where
127        P: FnMut(&A) -> Option<U>;
128
129    fn find<P>(&self, p: P) -> Option<A>
130    where
131        A: Copy,
132        P: FnMut(&A) -> bool;
133
134    fn find_cloned<P>(&self, p: P) -> Option<A>
135    where
136        A: Clone,
137        P: FnMut(&A) -> bool;
138
139    fn find_map<P, U>(&self, p: P) -> Option<U>
140    where
141        P: FnMut(&A) -> Option<U>;
142
143    fn find_set<P>(&self, p: P, item: A) -> bool
144    where
145        A: Copy,
146        P: FnMut(&A) -> bool;
147
148    fn find_set_cloned<P>(&self, p: P, item: A) -> bool
149    where
150        A: Clone,
151        P: FnMut(&A) -> bool;
152
153    fn find_set_or_add<P>(&self, p: P, item: A)
154    where
155        A: Copy,
156        P: FnMut(&A) -> bool;
157
158    fn find_set_or_add_cloned<P>(&self, p: P, item: A)
159    where
160        A: Clone,
161        P: FnMut(&A) -> bool;
162
163    fn find_set_if<P, F, I>(&self, p: P, item: F, i: I) -> bool
164    where
165        A: Copy,
166        F: FnMut() -> A,
167        P: FnMut(&A) -> bool,
168        I: FnMut(&A) -> bool;
169
170    fn find_set_if_cloned<P, F, I>(&self, p: P, item: F, i: I) -> bool
171    where
172        A: Clone,
173        F: FnMut() -> A,
174        P: FnMut(&A) -> bool,
175        I: FnMut(&A) -> bool;
176
177    fn find_set_if_or_add<P, F, I>(&self, p: P, item: F, i: I)
178    where
179        A: Copy,
180        F: FnMut() -> A,
181        P: FnMut(&A) -> bool,
182        I: FnMut(&A) -> bool;
183
184    fn find_set_if_or_add_cloned<P, F, I>(&self, p: P, item: F, i: I)
185    where
186        A: Clone,
187        F: FnMut() -> A,
188        P: FnMut(&A) -> bool,
189        I: FnMut(&A) -> bool;
190
191    fn find_remove<P>(&self, p: P) -> bool
192    where
193        A: Copy,
194        P: FnMut(&A) -> bool;
195
196    fn find_remove_cloned<P>(&self, p: P) -> bool
197    where
198        A: Clone,
199        P: FnMut(&A) -> bool;
200
201    fn extend(&self, source: impl IntoIterator<Item = A>)
202    where
203        A: Copy;
204
205    fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
206    where
207        A: Clone;
208
209    fn replace<P>(&self, what: P, with: impl IntoIterator<Item = A>)
210    where
211        A: Copy,
212        P: FnMut(&A) -> bool;
213
214    fn replace_cloned<P>(&self, what: P, with: impl IntoIterator<Item = A>)
215    where
216        A: Clone,
217        P: FnMut(&A) -> bool;
218
219    fn replace_keyed<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
220    where
221        A: Copy,
222        F: FnMut(&A) -> K,
223        K: Eq + Hash;
224
225    fn replace_keyed_cloned<F, K>(&self, f: F, source: impl IntoIterator<Item = A>) -> bool
226    where
227        A: Clone,
228        F: FnMut(&A) -> K,
229        K: Eq + Hash;
230
231    fn synchronize<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
232    where
233        A: Copy,
234        F: FnMut(&A) -> K,
235        K: Eq + Hash;
236
237    fn synchronize_cloned<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
238    where
239        A: Clone,
240        F: FnMut(&A) -> K,
241        K: Eq + Hash;
242
243    fn take(&self) -> Vec<A>;
244
245    #[cfg(feature = "spawn")]
246    fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
247    where
248        A: Copy + Send + Sync + 'static;
249
250    #[cfg(feature = "spawn")]
251    fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
252    where
253        A: Clone + Send + Sync + 'static;
254
255    #[cfg(feature = "spawn-local")]
256    fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
257    where
258        A: Copy + 'static;
259
260    #[cfg(feature = "spawn-local")]
261    fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
262    where
263        A: Clone + 'static;
264
265    fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
266    where
267        A: Copy,
268        P: FnMut(&A) -> bool;
269
270    fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
271    where
272        A: Clone,
273        P: FnMut(&A) -> bool;
274
275    fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
276    where
277        A: Copy,
278        P: FnMut(&A) -> S,
279        S: Signal<Item = bool>;
280
281    fn signal_vec_filter_signal_cloned<P, S>(
282        &self,
283        p: P,
284    ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
285    where
286        A: Clone,
287        P: FnMut(&A) -> S,
288        S: Signal<Item = bool>;
289
290    fn signal_vec_filter_map<P, U>(&self, p: P) -> FilterMap<MutableSignalVec<A>, P>
291    where
292        A: Copy,
293        P: FnMut(A) -> Option<U>;
294
295    fn signal_vec_filter_map_cloned<P, U>(&self, p: P) -> FilterMap<MutableSignalVec<A>, P>
296    where
297        A: Clone,
298        P: FnMut(A) -> Option<U>;
299}
300
301impl<A> MutableVecExt<A> for MutableVec<A> {
302    #[inline]
303    fn inspect_vec(&self, mut f: impl FnMut(&[A])) {
304        f(&self.lock_ref())
305    }
306
307    #[inline]
308    fn inspect_vec_mut(&self, mut f: impl FnMut(&mut MutableVecLockMut<A>)) {
309        f(&mut self.lock_mut())
310    }
311
312    fn map_vec<F, U>(&self, f: F) -> U
313    where
314        F: FnOnce(&[A]) -> U,
315    {
316        f(&self.lock_ref())
317    }
318
319    fn map_vec_mut<F, U>(&self, f: F) -> U
320    where
321        F: FnOnce(&mut MutableVecLockMut<A>) -> U,
322    {
323        f(&mut self.lock_mut())
324    }
325
326    /// Return parameter of F (changed) drives if the value should be written back,
327    /// and cause MutableVec change. If F returns false, no change is induced neither
328    /// reported.
329    fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
330    where
331        A: Copy,
332        P: FnMut(&A) -> bool,
333        F: FnMut(&mut A) -> bool,
334    {
335        self.entry(predicate)
336            .value()
337            .map(|mut value| value.inspect_mut(f))
338    }
339
340    /// Return parameter of F (changed) drives if the value should be written back,
341    /// and cause MutableVec change. If F returns false, no change is induced neither
342    /// reported.
343    fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
344    where
345        A: Clone,
346        P: FnMut(&A) -> bool,
347        F: FnMut(&mut A) -> bool,
348    {
349        self.entry_cloned(predicate)
350            .value()
351            .map(|mut value| value.inspect_mut(f))
352    }
353
354    fn map<F, U>(&self, f: F) -> Vec<U>
355    where
356        F: FnMut(&A) -> U,
357    {
358        self.lock_ref().iter().map(f).collect()
359    }
360
361    fn enumerate_map<F, U>(&self, mut f: F) -> Vec<U>
362    where
363        F: FnMut(usize, &A) -> U,
364    {
365        self.lock_ref()
366            .iter()
367            .enumerate()
368            .map(|(index, item)| f(index, item))
369            .collect()
370    }
371
372    fn filter<P>(&self, mut p: P) -> Vec<A>
373    where
374        A: Copy,
375        P: FnMut(&A) -> bool,
376    {
377        self.lock_ref().iter().filter(|&a| p(a)).copied().collect()
378    }
379
380    fn filter_cloned<P>(&self, mut p: P) -> Vec<A>
381    where
382        A: Clone,
383        P: FnMut(&A) -> bool,
384    {
385        self.lock_ref().iter().filter(|&a| p(a)).cloned().collect()
386    }
387
388    fn filter_map<P, U>(&self, p: P) -> Vec<U>
389    where
390        P: FnMut(&A) -> Option<U>,
391    {
392        self.lock_ref().iter().filter_map(p).collect()
393    }
394
395    fn find<P>(&self, mut p: P) -> Option<A>
396    where
397        A: Copy,
398        P: FnMut(&A) -> bool,
399    {
400        self.lock_ref().iter().find(|&a| p(a)).copied()
401    }
402
403    fn find_cloned<P>(&self, mut p: P) -> Option<A>
404    where
405        A: Clone,
406        P: FnMut(&A) -> bool,
407    {
408        self.lock_ref().iter().find(|&a| p(a)).cloned()
409    }
410
411    fn find_map<P, U>(&self, p: P) -> Option<U>
412    where
413        P: FnMut(&A) -> Option<U>,
414    {
415        self.lock_ref().iter().find_map(p)
416    }
417
418    fn find_set<P>(&self, p: P, item: A) -> bool
419    where
420        A: Copy,
421        P: FnMut(&A) -> bool,
422    {
423        self.entry(p).and_set(item).is_occupied()
424    }
425
426    fn find_set_cloned<P>(&self, p: P, item: A) -> bool
427    where
428        A: Clone,
429        P: FnMut(&A) -> bool,
430    {
431        self.entry_cloned(p).and_set(item).is_occupied()
432    }
433
434    fn find_set_or_add<P>(&self, p: P, item: A)
435    where
436        A: Copy,
437        P: FnMut(&A) -> bool,
438    {
439        self.entry(p).and_set_or_insert(item);
440    }
441
442    fn find_set_or_add_cloned<P>(&self, p: P, item: A)
443    where
444        A: Clone,
445        P: FnMut(&A) -> bool,
446    {
447        self.entry_cloned(p).and_set_or_insert(item);
448    }
449
450    fn find_set_if<P, F, I>(&self, p: P, mut item: F, mut i: I) -> bool
451    where
452        A: Copy,
453        F: FnMut() -> A,
454        P: FnMut(&A) -> bool,
455        I: FnMut(&A) -> bool,
456    {
457        self.entry(p)
458            .and_modify(|existing| {
459                existing.inspect_mut(|existing| {
460                    if i(existing) {
461                        *existing = item();
462                        true
463                    } else {
464                        false
465                    }
466                });
467            })
468            .is_occupied()
469    }
470
471    fn find_set_if_cloned<P, F, I>(&self, p: P, mut item: F, mut i: I) -> bool
472    where
473        A: Clone,
474        F: FnMut() -> A,
475        P: FnMut(&A) -> bool,
476        I: FnMut(&A) -> bool,
477    {
478        self.entry_cloned(p)
479            .and_modify(|existing| {
480                existing.inspect_mut(|existing| {
481                    if i(existing) {
482                        *existing = item();
483                        true
484                    } else {
485                        false
486                    }
487                });
488            })
489            .is_occupied()
490    }
491
492    fn find_set_if_or_add<P, F, I>(&self, p: P, mut item: F, mut i: I)
493    where
494        A: Copy,
495        F: FnMut() -> A,
496        P: FnMut(&A) -> bool,
497        I: FnMut(&A) -> bool,
498    {
499        self.entry(p)
500            .and_modify(|existing| {
501                existing.inspect_mut(|existing| {
502                    if i(existing) {
503                        *existing = item();
504                        true
505                    } else {
506                        false
507                    }
508                });
509            })
510            .or_insert_with(item);
511    }
512
513    fn find_set_if_or_add_cloned<P, F, I>(&self, p: P, mut item: F, mut i: I)
514    where
515        A: Clone,
516        F: FnMut() -> A,
517        P: FnMut(&A) -> bool,
518        I: FnMut(&A) -> bool,
519    {
520        self.entry_cloned(p)
521            .and_modify(|existing| {
522                existing.inspect_mut(|existing| {
523                    if i(existing) {
524                        *existing = item();
525                        true
526                    } else {
527                        false
528                    }
529                });
530            })
531            .or_insert_with(item);
532    }
533
534    fn find_remove<P>(&self, p: P) -> bool
535    where
536        A: Copy,
537        P: FnMut(&A) -> bool,
538    {
539        self.entry(p).remove().is_some()
540    }
541
542    fn find_remove_cloned<P>(&self, p: P) -> bool
543    where
544        A: Clone,
545        P: FnMut(&A) -> bool,
546    {
547        self.entry_cloned(p).remove().is_some()
548    }
549
550    fn extend(&self, source: impl IntoIterator<Item = A>)
551    where
552        A: Copy,
553    {
554        let mut lock = self.lock_mut();
555        for item in source.into_iter() {
556            lock.push(item);
557        }
558    }
559
560    fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
561    where
562        A: Clone,
563    {
564        let mut lock = self.lock_mut();
565        for item in source.into_iter() {
566            lock.push_cloned(item);
567        }
568    }
569
570    fn replace<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
571    where
572        A: Copy,
573        P: FnMut(&A) -> bool,
574    {
575        let mut lock = self.lock_mut();
576        lock.retain(|item| !what(item));
577        for item in with.into_iter() {
578            lock.push(item);
579        }
580    }
581
582    fn replace_cloned<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
583    where
584        A: Clone,
585        P: FnMut(&A) -> bool,
586    {
587        let mut lock = self.lock_mut();
588        lock.retain(|item| !what(item));
589        for item in with.into_iter() {
590            lock.push_cloned(item);
591        }
592    }
593
594    fn replace_keyed<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
595    where
596        A: Copy,
597        F: FnMut(&A) -> K,
598        K: Eq + Hash,
599    {
600        let source = source.into_iter().map(|item| (key(&item), item));
601        let mut source = collect_hash_map(source);
602
603        let mut lock = self.lock_mut();
604
605        let to_replace = lock
606            .iter()
607            .enumerate()
608            .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
609            .collect::<Vec<_>>();
610        for (index, item) in to_replace {
611            lock.set(index, item)
612        }
613
614        let extended = !source.is_empty();
615        for item in source.into_values() {
616            lock.push(item);
617        }
618
619        extended
620    }
621
622    fn replace_keyed_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
623    where
624        A: Clone,
625        F: FnMut(&A) -> K,
626        K: Eq + Hash,
627    {
628        let source = source.into_iter().map(|item| (key(&item), item));
629        let mut source = collect_hash_map(source);
630
631        let mut lock = self.lock_mut();
632
633        let to_replace = lock
634            .iter()
635            .enumerate()
636            .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
637            .collect::<Vec<_>>();
638        for (index, item) in to_replace {
639            lock.set_cloned(index, item)
640        }
641
642        let extended = !source.is_empty();
643        for item in source.into_values() {
644            lock.push_cloned(item);
645        }
646
647        extended
648    }
649
650    fn synchronize<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
651    where
652        A: Copy,
653        F: FnMut(&A) -> K,
654        K: Eq + Hash,
655    {
656        let source = source.into_iter().map(|item| (key(&item), item));
657        let mut source = collect_hash_map(source);
658
659        let mut lock = self.lock_mut();
660
661        let to_remove: Vec<_> = lock
662            .iter()
663            .enumerate()
664            .rev()
665            .filter_map(|(index, item)| match source.remove(&key(item)) {
666                Some(_) => None,
667                None => Some(index),
668            })
669            .collect();
670        // indexes go down, no need to calculate them anyhow
671        for index in to_remove.into_iter() {
672            lock.remove(index);
673        }
674
675        let extended = !source.is_empty();
676        for item in source.into_values() {
677            lock.push(item);
678        }
679
680        extended
681    }
682
683    fn synchronize_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
684    where
685        A: Clone,
686        F: FnMut(&A) -> K,
687        K: Eq + Hash,
688    {
689        let source = source.into_iter().map(|item| (key(&item), item));
690        let mut source = collect_hash_map(source);
691
692        let mut lock = self.lock_mut();
693
694        let to_remove = lock
695            .iter()
696            .enumerate()
697            .rev()
698            .filter_map(|(index, item)| match source.remove(&key(item)) {
699                Some(_) => None,
700                None => Some(index),
701            })
702            .collect::<Vec<_>>();
703        // indexes go down, no need to calculate them anyhow
704        for index in to_remove.into_iter() {
705            lock.remove(index);
706        }
707
708        let extended = !source.is_empty();
709        for item in source.into_values() {
710            lock.push_cloned(item);
711        }
712
713        extended
714    }
715
716    fn take(&self) -> Vec<A> {
717        self.lock_mut().drain(..).collect()
718    }
719
720    #[cfg(feature = "spawn")]
721    fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
722    where
723        A: Copy + Send + Sync + 'static,
724    {
725        source.feed(self.clone());
726    }
727
728    #[cfg(feature = "spawn")]
729    fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
730    where
731        A: Clone + Send + Sync + 'static,
732    {
733        source.feed_cloned(self.clone());
734    }
735
736    #[cfg(feature = "spawn-local")]
737    fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
738    where
739        A: Copy + 'static,
740    {
741        source.feed_local(self.clone());
742    }
743
744    #[cfg(feature = "spawn-local")]
745    fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
746    where
747        A: Clone + 'static,
748    {
749        source.feed_local_cloned(self.clone());
750    }
751
752    #[inline]
753    fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
754    where
755        A: Copy,
756        P: FnMut(&A) -> bool,
757    {
758        self.signal_vec().filter(p)
759    }
760
761    #[inline]
762    fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
763    where
764        A: Clone,
765        P: FnMut(&A) -> bool,
766    {
767        self.signal_vec_cloned().filter(p)
768    }
769
770    #[inline]
771    fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
772    where
773        A: Copy,
774        P: FnMut(&A) -> S,
775        S: Signal<Item = bool>,
776    {
777        self.signal_vec().filter_signal_cloned(p)
778    }
779
780    #[inline]
781    fn signal_vec_filter_signal_cloned<P, S>(
782        &self,
783        p: P,
784    ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
785    where
786        A: Clone,
787        P: FnMut(&A) -> S,
788        S: Signal<Item = bool>,
789    {
790        self.signal_vec_cloned().filter_signal_cloned(p)
791    }
792
793    #[inline]
794    fn signal_vec_filter_map<P, U>(&self, p: P) -> FilterMap<MutableSignalVec<A>, P>
795    where
796        A: Copy,
797        P: FnMut(A) -> Option<U>,
798    {
799        self.signal_vec().filter_map(p)
800    }
801
802    #[inline]
803    fn signal_vec_filter_map_cloned<P, U>(&self, p: P) -> FilterMap<MutableSignalVec<A>, P>
804    where
805        A: Clone,
806        P: FnMut(A) -> Option<U>,
807    {
808        self.signal_vec_cloned().filter_map(p)
809    }
810}
811
812pub trait SignalVecFinalizerExt: SignalVec + Sized {
813    #[inline]
814    fn first(self) -> impl Signal<Item = Option<Self::Item>>
815    where
816        Self::Item: Copy,
817    {
818        self.first_map(|i| *i)
819    }
820
821    fn first_cloned(self) -> impl Signal<Item = Option<Self::Item>>
822    where
823        Self::Item: Clone,
824    {
825        self.first_map(|i| i.clone())
826    }
827
828    fn first_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
829    where
830        F: FnMut(&Self::Item) -> U,
831    {
832        self.to_signal_map(move |items| items.first().map(&mut f))
833    }
834
835    #[inline]
836    fn last(self) -> impl Signal<Item = Option<Self::Item>>
837    where
838        Self::Item: Copy,
839    {
840        self.last_map(|i| *i)
841    }
842
843    fn last_cloned(self) -> impl Signal<Item = Option<Self::Item>>
844    where
845        Self::Item: Clone,
846    {
847        self.last_map(|i| i.clone())
848    }
849
850    fn last_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
851    where
852        F: FnMut(&Self::Item) -> U,
853    {
854        self.to_signal_map(move |items| items.last().map(&mut f))
855    }
856
857    fn all<F>(self, mut f: F) -> impl Signal<Item = bool>
858    where
859        F: FnMut(&Self::Item) -> bool,
860    {
861        self.to_signal_map(move |items| items.iter().all(&mut f))
862    }
863
864    fn any<F>(self, mut f: F) -> impl Signal<Item = bool>
865    where
866        F: FnMut(&Self::Item) -> bool,
867    {
868        self.to_signal_map(move |items| items.iter().any(&mut f))
869    }
870
871    #[inline]
872    fn any_item(self) -> impl Signal<Item = bool> {
873        self.len().neq(0)
874    }
875}
876
877impl<S: SignalVec + Sized> SignalVecFinalizerExt for S {}
878
879pub trait SignalVecFlattenExt: SignalVec + Sized {
880    fn flatten_ext(self) -> Flatten<Self>
881    where
882        Self::Item: SignalVec,
883    {
884        Flatten {
885            signal: Some(self),
886            inner: vec![],
887            pending: VecDeque::new(),
888        }
889    }
890}
891
892impl<S: SignalVec + Sized> SignalVecFlattenExt for S {}
893
894pub trait SignalTimeExt: Signal + Sized {
895    #[inline]
896    fn debounce<W, F>(
897        self,
898        window: W,
899    ) -> Debounce<Self, W, Self::Item, impl FnMut(Self::Item, Self::Item) -> Self::Item, F> {
900        Self::debounce_reduce(self, window, |_, value| -> Self::Item { value })
901    }
902
903    fn debounce_reduce<W, R, F>(self, window: W, reduce: R) -> Debounce<Self, W, Self::Item, R, F>
904    where
905        R: FnMut(Self::Item, Self::Item) -> Self::Item,
906    {
907        Debounce {
908            signal: Some(self),
909            window,
910            acc: None,
911            reduce,
912            future: None,
913            first: true,
914        }
915    }
916
917    #[inline]
918    fn throttle_ext<D, F>(
919        self,
920        delay: D,
921    ) -> Throttle<Self, D, Self::Item, impl FnMut(Self::Item, Self::Item) -> Self::Item, F> {
922        Self::throttle_reduce(self, delay, |_, value| value)
923    }
924
925    fn throttle_reduce<D, R, F>(self, delay: D, reduce: R) -> Throttle<Self, D, Self::Item, R, F> {
926        Throttle {
927            signal: Some(self),
928            delay,
929            acc: None,
930            reduce,
931            timeout: None,
932        }
933    }
934}
935
936impl<S: Signal + Sized> SignalTimeExt for S {}
937
938pin_project! {
939    #[derive(Debug)]
940    #[must_use = "Signals do nothing unless polled"]
941    pub struct Debounce<S, W, B, R, D> {
942        #[pin]
943        signal: Option<S>,
944        window: W,
945        acc: Option<B>,
946        reduce: R,
947        #[pin]
948        future: Option<D>,
949        first: bool,
950    }
951}
952
953impl<S, W, B, R, F> Signal for Debounce<S, W, B, R, F>
954where
955    S: Signal<Item = B>,
956    W: FnMut() -> F,
957    F: Future<Output = ()>,
958    R: FnMut(B, B) -> B,
959{
960    type Item = Option<B>;
961
962    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
963        let mut this = self.project();
964
965        let mut done = false;
966
967        loop {
968            match this
969                .signal
970                .as_mut()
971                .as_pin_mut()
972                .map(|signal| signal.poll_change(cx))
973            {
974                None => {
975                    done = true;
976                }
977                Some(Poll::Ready(None)) => {
978                    this.signal.set(None);
979                    this.future.set(Some((this.window)()));
980                    done = true;
981                }
982                Some(Poll::Ready(Some(value))) => {
983                    this.future.set(Some((this.window)()));
984                    *this.acc = Some(match this.acc.take() {
985                        None => value,
986                        Some(acc) => (this.reduce)(acc, value),
987                    });
988                    continue;
989                }
990                Some(Poll::Pending) => {}
991            }
992            break;
993        }
994
995        match this
996            .future
997            .as_mut()
998            .as_pin_mut()
999            .map(|delay| delay.poll(cx))
1000        {
1001            None => {}
1002            Some(Poll::Ready(_)) => {
1003                this.future.set(None);
1004                match this.acc.take() {
1005                    None => {}
1006                    Some(value) => {
1007                        *this.first = false;
1008                        return Poll::Ready(Some(Some(value)));
1009                    }
1010                }
1011            }
1012            Some(Poll::Pending) => {
1013                done = false;
1014            }
1015        }
1016
1017        if *this.first {
1018            *this.first = false;
1019            Poll::Ready(Some(None))
1020        } else if done {
1021            Poll::Ready(None)
1022        } else {
1023            Poll::Pending
1024        }
1025    }
1026}
1027
1028pin_project! {
1029    #[derive(Debug)]
1030    #[must_use = "Signals do nothing unless polled"]
1031    pub struct Throttle<S, D, B, R, F> {
1032        #[pin]
1033        signal: Option<S>,
1034        delay: D,
1035        acc: Option<B>,
1036        reduce: R,
1037        #[pin]
1038        timeout: Option<F>,
1039    }
1040}
1041
1042impl<S, D, B, R, F> Signal for Throttle<S, D, B, R, F>
1043where
1044    S: Signal<Item = B>,
1045    D: FnMut() -> F,
1046    F: Future<Output = ()>,
1047    R: FnMut(B, B) -> B,
1048{
1049    type Item = B;
1050
1051    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1052        let mut this = self.project();
1053
1054        let mut done = false;
1055
1056        loop {
1057            match this
1058                .signal
1059                .as_mut()
1060                .as_pin_mut()
1061                .map(|signal| signal.poll_change(cx))
1062            {
1063                None => {
1064                    done = true;
1065                }
1066                Some(Poll::Ready(None)) => {
1067                    this.signal.set(None);
1068                    done = true;
1069                }
1070                Some(Poll::Ready(Some(value))) => {
1071                    *this.acc = Some(match this.acc.take() {
1072                        None => value,
1073                        Some(acc) => (this.reduce)(acc, value),
1074                    });
1075
1076                    if this.timeout.is_none() {
1077                        this.timeout.set(Some((this.delay)()));
1078                        if let Some(Poll::Ready(())) =
1079                            this.timeout.as_mut().as_pin_mut().map(|f| f.poll(cx))
1080                        {
1081                            this.timeout.set(None);
1082                        }
1083
1084                        return Poll::Ready(this.acc.take());
1085                    }
1086
1087                    continue;
1088                }
1089                Some(Poll::Pending) => {}
1090            }
1091            break;
1092        }
1093
1094        match this
1095            .timeout
1096            .as_mut()
1097            .as_pin_mut()
1098            .map(|delay| delay.poll(cx))
1099        {
1100            None => {}
1101            Some(Poll::Ready(_)) => {
1102                this.timeout.set(None);
1103
1104                match this.acc.take() {
1105                    None => {}
1106                    Some(value) => {
1107                        return Poll::Ready(Some(value));
1108                    }
1109                }
1110            }
1111            Some(Poll::Pending) => {
1112                done = false;
1113            }
1114        }
1115
1116        if done {
1117            Poll::Ready(None)
1118        } else {
1119            Poll::Pending
1120        }
1121    }
1122}
1123
1124pub trait SignalExtMapBool
1125where
1126    Self: Sized,
1127{
1128    fn map_bool<T, TM: FnMut() -> T, FM: FnMut() -> T>(
1129        self,
1130        t: TM,
1131        f: FM,
1132    ) -> MapBool<Self, TM, FM> {
1133        MapBool {
1134            signal: self,
1135            true_mapper: t,
1136            false_mapper: f,
1137        }
1138    }
1139
1140    fn map_option<T, TM: FnMut() -> T>(self, t: TM) -> MapOption<Self, TM> {
1141        MapOption {
1142            signal: self,
1143            true_mapper: t,
1144        }
1145    }
1146}
1147
1148impl<S: Signal<Item = bool> + Sized> SignalExtMapBool for S {}
1149
1150pin_project! {
1151    #[derive(Debug)]
1152    #[must_use = "Signals do nothing unless polled"]
1153    pub struct MapBool<S, TM, FM> {
1154        #[pin]
1155        signal: S,
1156        true_mapper: TM,
1157        false_mapper: FM,
1158    }
1159}
1160
1161impl<T, S: Signal<Item = bool>, TM: FnMut() -> T, FM: FnMut() -> T> Signal for MapBool<S, TM, FM> {
1162    type Item = T;
1163
1164    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1165        let this = self.project();
1166
1167        this.signal.poll_change(cx).map(|opt| {
1168            opt.map(|value| {
1169                if value {
1170                    (this.true_mapper)()
1171                } else {
1172                    (this.false_mapper)()
1173                }
1174            })
1175        })
1176    }
1177}
1178
1179pin_project! {
1180    #[derive(Debug)]
1181    #[must_use = "Signals do nothing unless polled"]
1182    pub struct MapOption<S, TM> {
1183        #[pin]
1184        signal: S,
1185        true_mapper: TM,
1186    }
1187}
1188
1189impl<T, S: Signal<Item = bool>, TM: FnMut() -> T> Signal for MapOption<S, TM> {
1190    type Item = Option<T>;
1191
1192    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1193        let this = self.project();
1194
1195        this.signal
1196            .poll_change(cx)
1197            .map(|opt| opt.map(|value| value.then(this.true_mapper)))
1198    }
1199}
1200
1201pub trait SignalExtMapOption<T>
1202where
1203    Self: Sized,
1204{
1205    fn map_some<F, U>(self, f: F) -> MapSome<Self, T, F, U>
1206    where
1207        F: FnMut(T) -> U,
1208    {
1209        MapSome {
1210            signal: self,
1211            mapper: f,
1212            pt: PhantomData,
1213            pu: PhantomData,
1214        }
1215    }
1216
1217    fn map_some_default<F, U>(self, f: F) -> MapSomeDefault<Self, T, F, U>
1218    where
1219        F: FnMut(T) -> U,
1220        U: Default,
1221    {
1222        MapSomeDefault {
1223            signal: self,
1224            mapper: f,
1225            pt: PhantomData,
1226            pu: PhantomData,
1227        }
1228    }
1229
1230    fn and_then_some<F, U>(self, f: F) -> AndThenSome<Self, T, F, U>
1231    where
1232        F: FnMut(T) -> Option<U>,
1233    {
1234        AndThenSome {
1235            signal: self,
1236            mapper: f,
1237            pt: PhantomData,
1238            pu: PhantomData,
1239        }
1240    }
1241
1242    fn unwrap_or_default(self) -> UnwrapOrDefault<Self, T>
1243    where
1244        T: Default,
1245    {
1246        UnwrapOrDefault {
1247            signal: self,
1248            pt: PhantomData,
1249        }
1250    }
1251}
1252
1253impl<T, S: Signal<Item = Option<T>> + Sized> SignalExtMapOption<T> for S {}
1254
1255pin_project! {
1256    #[derive(Debug)]
1257    #[must_use = "Signals do nothing unless polled"]
1258    pub struct MapSome<S, T, F, U> {
1259        #[pin]
1260        signal: S,
1261        mapper: F,
1262        pt: PhantomData<T>,
1263        pu: PhantomData<U>,
1264    }
1265}
1266
1267impl<T, S, F, U> Signal for MapSome<S, T, F, U>
1268where
1269    S: Signal<Item = Option<T>>,
1270    F: FnMut(T) -> U,
1271{
1272    type Item = Option<U>;
1273
1274    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1275        let this = self.project();
1276        this.signal
1277            .poll_change(cx)
1278            .map(|opt| opt.map(|opt| opt.map(this.mapper)))
1279    }
1280}
1281
1282pin_project! {
1283    #[derive(Debug)]
1284    #[must_use = "Signals do nothing unless polled"]
1285    pub struct MapSomeDefault<S, T, F, U> {
1286        #[pin]
1287        signal: S,
1288        mapper: F,
1289        pt: PhantomData<T>,
1290        pu: PhantomData<U>,
1291    }
1292}
1293
1294impl<T, S, F, U> Signal for MapSomeDefault<S, T, F, U>
1295where
1296    S: Signal<Item = Option<T>>,
1297    F: FnMut(T) -> U,
1298    U: Default,
1299{
1300    type Item = U;
1301
1302    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1303        let this = self.project();
1304        this.signal
1305            .poll_change(cx)
1306            .map(|opt| opt.map(|opt| opt.map(this.mapper).unwrap_or_default()))
1307    }
1308}
1309
1310pin_project! {
1311    #[derive(Debug)]
1312    #[must_use = "Signals do nothing unless polled"]
1313    pub struct AndThenSome<S, T, F, U> {
1314        #[pin]
1315        signal: S,
1316        mapper: F,
1317        pt: PhantomData<T>,
1318        pu: PhantomData<U>,
1319    }
1320}
1321
1322impl<T, S, F, U> Signal for AndThenSome<S, T, F, U>
1323where
1324    S: Signal<Item = Option<T>>,
1325    F: FnMut(T) -> Option<U>,
1326{
1327    type Item = Option<U>;
1328
1329    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1330        let this = self.project();
1331        this.signal
1332            .poll_change(cx)
1333            .map(|opt| opt.map(|opt| opt.and_then(this.mapper)))
1334    }
1335}
1336
1337pin_project! {
1338    #[derive(Debug)]
1339    #[must_use = "Signals do nothing unless polled"]
1340    pub struct UnwrapOrDefault<S, T> {
1341        #[pin]
1342        signal: S,
1343        pt: PhantomData<T>,
1344    }
1345}
1346
1347impl<T, S> Signal for UnwrapOrDefault<S, T>
1348where
1349    S: Signal<Item = Option<T>>,
1350    T: Default,
1351{
1352    type Item = T;
1353
1354    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1355        self.project()
1356            .signal
1357            .poll_change(cx)
1358            .map(|opt| opt.map(|opt| opt.unwrap_or_default()))
1359    }
1360}
1361
1362#[cfg(test)]
1363mod test {
1364    use futures_signals::signal_vec::MutableVec;
1365
1366    use crate::MutableVecExt;
1367
1368    #[test]
1369    fn replace_keyed() {
1370        let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1371        assert_eq!(vec.replace_keyed(|(k, _)| *k, [("b", 20), ("d", 4)]), true);
1372        assert_eq!(
1373            vec.lock_ref().as_slice(),
1374            &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1375        );
1376    }
1377
1378    #[test]
1379    fn replace_keyed_cloned() {
1380        let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1381        assert_eq!(
1382            vec.replace_keyed_cloned(|(k, _)| *k, [("b", 20), ("d", 4)]),
1383            true
1384        );
1385        assert_eq!(
1386            vec.lock_ref().as_slice(),
1387            &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1388        );
1389    }
1390}