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