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 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 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 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 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}