1use futures_signals::{
2 signal::{Mutable, Signal, SignalExt},
3 signal_vec::{
4 Filter, FilterSignalCloned, MutableSignalVec, MutableVec, MutableVecLockMut, SignalVec,
5 SignalVecExt,
6 },
7};
8use pin_project_lite::pin_project;
9use std::{
10 collections::VecDeque,
11 hash::Hash,
12 marker::PhantomData,
13 mem,
14 pin::Pin,
15 task::{Context, Poll},
16};
17
18use crate::{Flatten, MutableVecEntry, SignalVecSpawn};
19
20#[cfg(feature = "ahash")]
21type Hasher = ahash::RandomState;
22#[cfg(not(feature = "ahash"))]
23type Hasher = std::hash::RandomState;
24
25type HashMap<K, V> = std::collections::HashMap<K, V, Hasher>;
26
27fn collect_hash_map<K, V, I>(iter: I) -> HashMap<K, V>
28where
29 K: Eq + Hash,
30 I: Iterator<Item = (K, V)>,
31{
32 #[cfg(feature = "ahash")]
33 {
34 let mut map = HashMap::with_hasher(Hasher::with_seed(250402117));
35 map.extend(iter);
36 map
37 }
38 #[cfg(not(feature = "ahash"))]
39 iter.collect()
40}
41
42pub trait MutableExt<A> {
43 fn inspect(&self, f: impl FnOnce(&A));
44 fn inspect_mut(&self, f: impl FnOnce(&mut A));
45
46 fn map<B>(&self, f: impl FnOnce(&A) -> B) -> B;
47 fn map_mut<B>(&self, f: impl FnOnce(&mut A) -> B) -> B;
48
49 fn apply(&self, f: impl FnOnce(A) -> A)
50 where
51 A: Copy;
52 fn apply_cloned(&self, f: impl FnOnce(A) -> A)
53 where
54 A: Clone;
55
56 fn into_inner(self) -> A
57 where
58 A: Default,
59 Self: Sized,
60 {
61 self.map_mut(mem::take)
62 }
63
64 fn take(&self) -> A
65 where
66 A: Default,
67 {
68 self.map_mut(mem::take)
69 }
70}
71
72impl<A> MutableExt<A> for Mutable<A> {
73 fn inspect(&self, f: impl FnOnce(&A)) {
74 f(&self.lock_ref())
75 }
76
77 fn inspect_mut(&self, f: impl FnOnce(&mut A)) {
78 f(&mut self.lock_mut())
79 }
80
81 fn map<B>(&self, f: impl FnOnce(&A) -> B) -> B {
82 f(&self.lock_ref())
83 }
84
85 fn map_mut<B>(&self, f: impl FnOnce(&mut A) -> B) -> B {
86 f(&mut self.lock_mut())
87 }
88
89 fn apply(&self, f: impl FnOnce(A) -> A)
90 where
91 A: Copy,
92 {
93 self.set(f(self.get()))
94 }
95
96 fn apply_cloned(&self, f: impl FnOnce(A) -> A)
97 where
98 A: Clone,
99 {
100 self.set(f(self.get_cloned()))
101 }
102}
103
104pub trait MutableVecExt<A> {
105 fn map_vec<F, U>(&self, f: F) -> U
106 where
107 F: FnOnce(&[A]) -> U;
108
109 fn map_vec_mut<F, U>(&self, f: F) -> U
110 where
111 F: FnOnce(&mut MutableVecLockMut<A>) -> U;
112
113 fn inspect_vec(&self, f: impl FnMut(&[A]));
114 fn inspect_vec_mut(&self, f: impl FnMut(&mut MutableVecLockMut<A>));
115
116 fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
117 where
118 A: Copy,
119 P: FnMut(&A) -> bool,
120 F: FnOnce(&mut A) -> bool;
121
122 fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
123 where
124 A: Clone,
125 P: FnMut(&A) -> bool,
126 F: FnOnce(&mut A) -> bool;
127
128 fn map<F, U>(&self, f: F) -> Vec<U>
129 where
130 F: FnMut(&A) -> U;
131
132 fn enumerate_map<F, U>(&self, f: F) -> Vec<U>
133 where
134 F: FnMut(usize, &A) -> U;
135
136 fn filter<P>(&self, p: P) -> Vec<A>
137 where
138 A: Copy,
139 P: FnMut(&A) -> bool;
140
141 fn filter_cloned<P>(&self, p: P) -> Vec<A>
142 where
143 A: Clone,
144 P: FnMut(&A) -> bool;
145
146 fn filter_map<P, U>(&self, p: P) -> Vec<U>
147 where
148 P: FnMut(&A) -> Option<U>;
149
150 fn find<P>(&self, p: P) -> Option<A>
151 where
152 A: Copy,
153 P: FnMut(&A) -> bool;
154
155 fn find_cloned<P>(&self, p: P) -> Option<A>
156 where
157 A: Clone,
158 P: FnMut(&A) -> bool;
159
160 fn find_map<P, U>(&self, p: P) -> Option<U>
161 where
162 P: FnMut(&A) -> Option<U>;
163
164 fn find_set<P>(&self, p: P, item: A) -> bool
165 where
166 A: Copy,
167 P: FnMut(&A) -> bool;
168
169 fn find_set_cloned<P>(&self, p: P, item: A) -> bool
170 where
171 A: Clone,
172 P: FnMut(&A) -> bool;
173
174 fn find_set_or_add<P>(&self, p: P, item: A)
175 where
176 A: Copy,
177 P: FnMut(&A) -> bool;
178
179 fn find_set_or_add_cloned<P>(&self, p: P, item: A)
180 where
181 A: Clone,
182 P: FnMut(&A) -> bool;
183
184 fn find_remove<P>(&self, p: P) -> bool
185 where
186 A: Copy,
187 P: FnMut(&A) -> bool;
188
189 fn find_remove_cloned<P>(&self, p: P) -> bool
190 where
191 A: Clone,
192 P: FnMut(&A) -> bool;
193
194 fn extend(&self, source: impl IntoIterator<Item = A>)
195 where
196 A: Copy;
197
198 fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
199 where
200 A: Clone;
201
202 fn replace<P>(&self, what: P, with: impl IntoIterator<Item = A>)
203 where
204 A: Copy,
205 P: FnMut(&A) -> bool;
206
207 fn replace_cloned<P>(&self, what: P, with: impl IntoIterator<Item = A>)
208 where
209 A: Clone,
210 P: FnMut(&A) -> bool;
211
212 fn replace_keyed<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
213 where
214 A: Copy,
215 F: FnMut(&A) -> K,
216 K: Eq + Hash;
217
218 fn replace_keyed_cloned<F, K>(&self, f: F, source: impl IntoIterator<Item = A>) -> bool
219 where
220 A: Clone,
221 F: FnMut(&A) -> K,
222 K: Eq + Hash;
223
224 fn synchronize<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
225 where
226 A: Copy,
227 F: FnMut(&A) -> K,
228 K: Eq + Hash;
229
230 fn synchronize_cloned<F, K>(&self, key: F, source: impl IntoIterator<Item = A>) -> bool
231 where
232 A: Clone,
233 F: FnMut(&A) -> K,
234 K: Eq + Hash;
235
236 #[cfg(feature = "spawn")]
237 fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
238 where
239 A: Copy + Send + Sync + 'static;
240
241 #[cfg(feature = "spawn")]
242 fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
243 where
244 A: Clone + Send + Sync + 'static;
245
246 #[cfg(feature = "spawn-local")]
247 fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
248 where
249 A: Copy + 'static;
250
251 #[cfg(feature = "spawn-local")]
252 fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
253 where
254 A: Clone + 'static;
255
256 fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
257 where
258 A: Copy,
259 P: FnMut(&A) -> bool;
260
261 fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
262 where
263 A: Clone,
264 P: FnMut(&A) -> bool;
265
266 fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
267 where
268 A: Copy,
269 P: FnMut(&A) -> S,
270 S: Signal<Item = bool>;
271
272 fn signal_vec_filter_signal_cloned<P, S>(
273 &self,
274 p: P,
275 ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
276 where
277 A: Clone,
278 P: FnMut(&A) -> S,
279 S: Signal<Item = bool>;
280}
281
282impl<A> MutableVecExt<A> for MutableVec<A> {
283 fn map_vec<F, U>(&self, f: F) -> U
284 where
285 F: FnOnce(&[A]) -> U,
286 {
287 f(&self.lock_ref())
288 }
289
290 fn map_vec_mut<F, U>(&self, f: F) -> U
291 where
292 F: FnOnce(&mut MutableVecLockMut<A>) -> U,
293 {
294 f(&mut self.lock_mut())
295 }
296
297 #[inline]
298 fn inspect_vec(&self, mut f: impl FnMut(&[A])) {
299 f(&self.lock_ref())
300 }
301
302 #[inline]
303 fn inspect_vec_mut(&self, mut f: impl FnMut(&mut MutableVecLockMut<A>)) {
304 f(&mut self.lock_mut())
305 }
306
307 fn find_inspect_mut<P, F>(&self, predicate: P, f: F) -> Option<bool>
311 where
312 A: Copy,
313 P: FnMut(&A) -> bool,
314 F: FnOnce(&mut A) -> bool,
315 {
316 self.entry(predicate)
317 .value()
318 .map(|mut value| value.inspect_mut(f))
319 }
320
321 fn find_inspect_mut_cloned<P, F>(&self, predicate: P, f: F) -> Option<bool>
325 where
326 A: Clone,
327 P: FnMut(&A) -> bool,
328 F: FnOnce(&mut A) -> bool,
329 {
330 self.entry_cloned(predicate)
331 .value()
332 .map(|mut value| value.inspect_mut(f))
333 }
334
335 fn map<F, U>(&self, f: F) -> Vec<U>
336 where
337 F: FnMut(&A) -> U,
338 {
339 self.lock_ref().iter().map(f).collect()
340 }
341
342 fn enumerate_map<F, U>(&self, mut f: F) -> Vec<U>
343 where
344 F: FnMut(usize, &A) -> U,
345 {
346 self.lock_ref()
347 .iter()
348 .enumerate()
349 .map(|(index, item)| f(index, item))
350 .collect()
351 }
352
353 fn filter<P>(&self, mut p: P) -> Vec<A>
354 where
355 A: Copy,
356 P: FnMut(&A) -> bool,
357 {
358 self.lock_ref().iter().filter(|&a| p(a)).copied().collect()
359 }
360
361 fn filter_cloned<P>(&self, mut p: P) -> Vec<A>
362 where
363 A: Clone,
364 P: FnMut(&A) -> bool,
365 {
366 self.lock_ref().iter().filter(|&a| p(a)).cloned().collect()
367 }
368
369 fn filter_map<P, U>(&self, p: P) -> Vec<U>
370 where
371 P: FnMut(&A) -> Option<U>,
372 {
373 self.lock_ref().iter().filter_map(p).collect()
374 }
375
376 fn find<P>(&self, mut p: P) -> Option<A>
377 where
378 A: Copy,
379 P: FnMut(&A) -> bool,
380 {
381 self.lock_ref().iter().find(|&a| p(a)).copied()
382 }
383
384 fn find_cloned<P>(&self, mut p: P) -> Option<A>
385 where
386 A: Clone,
387 P: FnMut(&A) -> bool,
388 {
389 self.lock_ref().iter().find(|&a| p(a)).cloned()
390 }
391
392 fn find_map<P, U>(&self, p: P) -> Option<U>
393 where
394 P: FnMut(&A) -> Option<U>,
395 {
396 self.lock_ref().iter().find_map(p)
397 }
398
399 fn find_set<P>(&self, p: P, item: A) -> bool
400 where
401 A: Copy,
402 P: FnMut(&A) -> bool,
403 {
404 self.entry(p).and_set(item).is_occupied()
405 }
406
407 fn find_set_cloned<P>(&self, p: P, item: A) -> bool
408 where
409 A: Clone,
410 P: FnMut(&A) -> bool,
411 {
412 self.entry_cloned(p).and_set(item).is_occupied()
413 }
414
415 fn find_set_or_add<P>(&self, p: P, item: A)
416 where
417 A: Copy,
418 P: FnMut(&A) -> bool,
419 {
420 self.entry(p).and_set_or_insert(item);
421 }
422
423 fn find_set_or_add_cloned<P>(&self, p: P, item: A)
424 where
425 A: Clone,
426 P: FnMut(&A) -> bool,
427 {
428 self.entry_cloned(p).and_set_or_insert(item);
429 }
430
431 fn find_remove<P>(&self, p: P) -> bool
432 where
433 A: Copy,
434 P: FnMut(&A) -> bool,
435 {
436 self.entry(p).remove().is_some()
437 }
438
439 fn find_remove_cloned<P>(&self, p: P) -> bool
440 where
441 A: Clone,
442 P: FnMut(&A) -> bool,
443 {
444 self.entry_cloned(p).remove().is_some()
445 }
446
447 fn extend(&self, source: impl IntoIterator<Item = A>)
448 where
449 A: Copy,
450 {
451 let mut lock = self.lock_mut();
452 for item in source.into_iter() {
453 lock.push(item);
454 }
455 }
456
457 fn extend_cloned(&self, source: impl IntoIterator<Item = A>)
458 where
459 A: Clone,
460 {
461 let mut lock = self.lock_mut();
462 for item in source.into_iter() {
463 lock.push_cloned(item);
464 }
465 }
466
467 fn replace<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
468 where
469 A: Copy,
470 P: FnMut(&A) -> bool,
471 {
472 let mut lock = self.lock_mut();
473 lock.retain(|item| !what(item));
474 for item in with.into_iter() {
475 lock.push(item);
476 }
477 }
478
479 fn replace_cloned<P>(&self, mut what: P, with: impl IntoIterator<Item = A>)
480 where
481 A: Clone,
482 P: FnMut(&A) -> bool,
483 {
484 let mut lock = self.lock_mut();
485 lock.retain(|item| !what(item));
486 for item in with.into_iter() {
487 lock.push_cloned(item);
488 }
489 }
490
491 fn replace_keyed<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
492 where
493 A: Copy,
494 F: FnMut(&A) -> K,
495 K: Eq + Hash,
496 {
497 let source = source.into_iter().map(|item| (key(&item), item));
498 let mut source = collect_hash_map(source);
499
500 let mut lock = self.lock_mut();
501
502 let to_replace = lock
503 .iter()
504 .enumerate()
505 .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
506 .collect::<Vec<_>>();
507 for (index, item) in to_replace {
508 lock.set(index, item)
509 }
510
511 let extended = !source.is_empty();
512 for item in source.into_values() {
513 lock.push(item);
514 }
515
516 extended
517 }
518
519 fn replace_keyed_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
520 where
521 A: Clone,
522 F: FnMut(&A) -> K,
523 K: Eq + Hash,
524 {
525 let source = source.into_iter().map(|item| (key(&item), item));
526 let mut source = collect_hash_map(source);
527
528 let mut lock = self.lock_mut();
529
530 let to_replace = lock
531 .iter()
532 .enumerate()
533 .filter_map(|(index, item)| source.remove(&key(item)).map(|item| (index, item)))
534 .collect::<Vec<_>>();
535 for (index, item) in to_replace {
536 lock.set_cloned(index, item)
537 }
538
539 let extended = !source.is_empty();
540 for item in source.into_values() {
541 lock.push_cloned(item);
542 }
543
544 extended
545 }
546
547 fn synchronize<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
548 where
549 A: Copy,
550 F: FnMut(&A) -> K,
551 K: Eq + Hash,
552 {
553 let source = source.into_iter().map(|item| (key(&item), item));
554 let mut source = collect_hash_map(source);
555
556 let mut lock = self.lock_mut();
557
558 let to_remove: Vec<_> = lock
559 .iter()
560 .enumerate()
561 .rev()
562 .filter_map(|(index, item)| match source.remove(&key(item)) {
563 Some(_) => None,
564 None => Some(index),
565 })
566 .collect();
567 for index in to_remove.into_iter() {
569 lock.remove(index);
570 }
571
572 let extended = !source.is_empty();
573 for item in source.into_values() {
574 lock.push(item);
575 }
576
577 extended
578 }
579
580 fn synchronize_cloned<F, K>(&self, mut key: F, source: impl IntoIterator<Item = A>) -> bool
581 where
582 A: Clone,
583 F: FnMut(&A) -> K,
584 K: Eq + Hash,
585 {
586 let source = source.into_iter().map(|item| (key(&item), item));
587 let mut source = collect_hash_map(source);
588
589 let mut lock = self.lock_mut();
590
591 let to_remove = lock
592 .iter()
593 .enumerate()
594 .rev()
595 .filter_map(|(index, item)| match source.remove(&key(item)) {
596 Some(_) => None,
597 None => Some(index),
598 })
599 .collect::<Vec<_>>();
600 for index in to_remove.into_iter() {
602 lock.remove(index);
603 }
604
605 let extended = !source.is_empty();
606 for item in source.into_values() {
607 lock.push_cloned(item);
608 }
609
610 extended
611 }
612
613 #[cfg(feature = "spawn")]
614 fn feed(&self, source: impl SignalVec<Item = A> + Send + 'static)
615 where
616 A: Copy + Send + Sync + 'static,
617 {
618 source.feed(self.clone());
619 }
620
621 #[cfg(feature = "spawn")]
622 fn feed_cloned(&self, source: impl SignalVec<Item = A> + Send + 'static)
623 where
624 A: Clone + Send + Sync + 'static,
625 {
626 source.feed_cloned(self.clone());
627 }
628
629 #[cfg(feature = "spawn-local")]
630 fn feed_local(&self, source: impl SignalVec<Item = A> + 'static)
631 where
632 A: Copy + 'static,
633 {
634 source.feed_local(self.clone());
635 }
636
637 #[cfg(feature = "spawn-local")]
638 fn feed_local_cloned(&self, source: impl SignalVec<Item = A> + 'static)
639 where
640 A: Clone + 'static,
641 {
642 source.feed_local_cloned(self.clone());
643 }
644
645 fn signal_vec_filter<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
646 where
647 A: Copy,
648 P: FnMut(&A) -> bool,
649 {
650 self.signal_vec().filter(p)
651 }
652
653 fn signal_vec_filter_cloned<P>(&self, p: P) -> Filter<MutableSignalVec<A>, P>
654 where
655 A: Clone,
656 P: FnMut(&A) -> bool,
657 {
658 self.signal_vec_cloned().filter(p)
659 }
660
661 fn signal_vec_filter_signal<P, S>(&self, p: P) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
662 where
663 A: Copy,
664 P: FnMut(&A) -> S,
665 S: Signal<Item = bool>,
666 {
667 self.signal_vec().filter_signal_cloned(p)
668 }
669
670 fn signal_vec_filter_signal_cloned<P, S>(
671 &self,
672 p: P,
673 ) -> FilterSignalCloned<MutableSignalVec<A>, S, P>
674 where
675 A: Clone,
676 P: FnMut(&A) -> S,
677 S: Signal<Item = bool>,
678 {
679 self.signal_vec_cloned().filter_signal_cloned(p)
680 }
681}
682
683pub trait SignalVecFinalizerExt: SignalVec + Sized {
684 #[inline]
685 fn first(self) -> impl Signal<Item = Option<Self::Item>>
686 where
687 Self::Item: Copy,
688 {
689 self.first_map(|i| *i)
690 }
691
692 fn first_cloned(self) -> impl Signal<Item = Option<Self::Item>>
693 where
694 Self::Item: Clone,
695 {
696 self.first_map(|i| i.clone())
697 }
698
699 fn first_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
700 where
701 F: FnMut(&Self::Item) -> U,
702 {
703 self.to_signal_map(move |items| items.first().map(&mut f))
704 }
705
706 #[inline]
707 fn last(self) -> impl Signal<Item = Option<Self::Item>>
708 where
709 Self::Item: Copy,
710 {
711 self.last_map(|i| *i)
712 }
713
714 fn last_cloned(self) -> impl Signal<Item = Option<Self::Item>>
715 where
716 Self::Item: Clone,
717 {
718 self.last_map(|i| i.clone())
719 }
720
721 fn last_map<F, U>(self, mut f: F) -> impl Signal<Item = Option<U>>
722 where
723 F: FnMut(&Self::Item) -> U,
724 {
725 self.to_signal_map(move |items| items.last().map(&mut f))
726 }
727
728 fn all<F>(self, mut f: F) -> impl Signal<Item = bool>
729 where
730 F: FnMut(&Self::Item) -> bool,
731 {
732 self.to_signal_map(move |items| items.iter().all(&mut f))
733 }
734
735 fn any<F>(self, mut f: F) -> impl Signal<Item = bool>
736 where
737 F: FnMut(&Self::Item) -> bool,
738 {
739 self.to_signal_map(move |items| items.iter().any(&mut f))
740 }
741
742 #[inline]
743 fn any_item(self) -> impl Signal<Item = bool> {
744 self.len().neq(0)
745 }
746
747 fn seq(self) -> Sequence<Self> {
748 Sequence {
749 signal: self,
750 sequence: 0,
751 }
752 }
753}
754
755impl<S: SignalVec + Sized> SignalVecFinalizerExt for S {}
756
757pub trait SignalVecFlattenExt: SignalVec + Sized {
758 fn flatten_ext(self) -> Flatten<Self>
759 where
760 Self::Item: SignalVec,
761 {
762 Flatten {
763 signal: Some(self),
764 inner: vec![],
765 pending: VecDeque::new(),
766 }
767 }
768}
769
770impl<S: SignalVec + Sized> SignalVecFlattenExt for S {}
771
772pub trait SignalExtMapBool
773where
774 Self: Sized,
775{
776 fn map_bool<T, TM: FnMut() -> T, FM: FnMut() -> T>(
777 self,
778 t: TM,
779 f: FM,
780 ) -> MapBool<Self, TM, FM> {
781 MapBool {
782 signal: self,
783 true_mapper: t,
784 false_mapper: f,
785 }
786 }
787
788 fn map_option<T, TM: FnMut() -> T>(self, t: TM) -> MapOption<Self, TM> {
789 MapOption {
790 signal: self,
791 true_mapper: t,
792 }
793 }
794}
795
796impl<S: Signal<Item = bool> + Sized> SignalExtMapBool for S {}
797
798pin_project! {
799 #[derive(Debug)]
800 #[must_use = "Signals do nothing unless polled"]
801 pub struct MapBool<S, TM, FM> {
802 #[pin]
803 signal: S,
804 true_mapper: TM,
805 false_mapper: FM,
806 }
807}
808
809impl<T, S: Signal<Item = bool>, TM: FnMut() -> T, FM: FnMut() -> T> Signal for MapBool<S, TM, FM> {
810 type Item = T;
811
812 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
813 let this = self.project();
814
815 this.signal.poll_change(cx).map(|opt| {
816 opt.map(|value| {
817 if value {
818 (this.true_mapper)()
819 } else {
820 (this.false_mapper)()
821 }
822 })
823 })
824 }
825}
826
827pin_project! {
828 #[derive(Debug)]
829 #[must_use = "Signals do nothing unless polled"]
830 pub struct MapOption<S, TM> {
831 #[pin]
832 signal: S,
833 true_mapper: TM,
834 }
835}
836
837impl<T, S: Signal<Item = bool>, TM: FnMut() -> T> Signal for MapOption<S, TM> {
838 type Item = Option<T>;
839
840 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
841 let this = self.project();
842
843 this.signal
844 .poll_change(cx)
845 .map(|opt| opt.map(|value| value.then(this.true_mapper)))
846 }
847}
848
849pub trait SignalExtMapOption<T>
850where
851 Self: Sized,
852{
853 fn map_some<F, U>(self, f: F) -> MapSome<Self, T, F, U>
854 where
855 F: FnMut(&T) -> U,
856 {
857 MapSome {
858 signal: self,
859 mapper: f,
860 pt: PhantomData,
861 pu: PhantomData,
862 }
863 }
864
865 fn map_some_default<F, U>(self, f: F) -> MapSomeDefault<Self, T, F, U>
866 where
867 F: FnMut(&T) -> U,
868 U: Default,
869 {
870 MapSomeDefault {
871 signal: self,
872 mapper: f,
873 pt: PhantomData,
874 pu: PhantomData,
875 }
876 }
877
878 fn and_then_some<F, U>(self, f: F) -> AndThenSome<Self, T, F, U>
879 where
880 F: FnMut(&T) -> Option<U>,
881 {
882 AndThenSome {
883 signal: self,
884 mapper: f,
885 pt: PhantomData,
886 pu: PhantomData,
887 }
888 }
889
890 fn unwrap_or_default(self) -> UnwrapOrDefault<Self, T>
891 where
892 T: Default,
893 {
894 UnwrapOrDefault {
895 signal: self,
896 pt: PhantomData,
897 }
898 }
899}
900
901impl<T, S: Signal<Item = Option<T>> + Sized> SignalExtMapOption<T> for S {}
902
903pin_project! {
904 #[derive(Debug)]
905 #[must_use = "Signals do nothing unless polled"]
906 pub struct MapSome<S, T, F, U> {
907 #[pin]
908 signal: S,
909 mapper: F,
910 pt: PhantomData<T>,
911 pu: PhantomData<U>,
912 }
913}
914
915impl<T, S, F, U> Signal for MapSome<S, T, F, U>
916where
917 S: Signal<Item = Option<T>>,
918 F: FnMut(&T) -> U,
919{
920 type Item = Option<U>;
921
922 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
923 let this = self.project();
924 this.signal
925 .poll_change(cx)
926 .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value))))
927 }
928}
929
930pin_project! {
931 #[derive(Debug)]
932 #[must_use = "Signals do nothing unless polled"]
933 pub struct MapSomeDefault<S, T, F, U> {
934 #[pin]
935 signal: S,
936 mapper: F,
937 pt: PhantomData<T>,
938 pu: PhantomData<U>,
939 }
940}
941
942impl<T, S, F, U> Signal for MapSomeDefault<S, T, F, U>
943where
944 S: Signal<Item = Option<T>>,
945 F: FnMut(&T) -> U,
946 U: Default,
947{
948 type Item = U;
949
950 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
951 let this = self.project();
952 this.signal
953 .poll_change(cx)
954 .map(|opt| opt.map(|opt| opt.map(|value| (this.mapper)(&value)).unwrap_or_default()))
955 }
956}
957
958pin_project! {
959 #[derive(Debug)]
960 #[must_use = "Signals do nothing unless polled"]
961 pub struct AndThenSome<S, T, F, U> {
962 #[pin]
963 signal: S,
964 mapper: F,
965 pt: PhantomData<T>,
966 pu: PhantomData<U>,
967 }
968}
969
970impl<T, S, F, U> Signal for AndThenSome<S, T, F, U>
971where
972 S: Signal<Item = Option<T>>,
973 F: FnMut(&T) -> Option<U>,
974{
975 type Item = Option<U>;
976
977 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
978 let this = self.project();
979 this.signal
980 .poll_change(cx)
981 .map(|opt| opt.map(|opt| opt.and_then(|value| (this.mapper)(&value))))
982 }
983}
984
985pin_project! {
986 #[derive(Debug)]
987 #[must_use = "Signals do nothing unless polled"]
988 pub struct UnwrapOrDefault<S, T> {
989 #[pin]
990 signal: S,
991 pt: PhantomData<T>,
992 }
993}
994
995impl<T, S> Signal for UnwrapOrDefault<S, T>
996where
997 S: Signal<Item = Option<T>>,
998 T: Default,
999{
1000 type Item = T;
1001
1002 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1003 self.project()
1004 .signal
1005 .poll_change(cx)
1006 .map(|opt| opt.map(|opt| opt.unwrap_or_default()))
1007 }
1008}
1009
1010pin_project! {
1011 #[derive(Debug)]
1012 #[must_use = "Signals do nothing unless polled"]
1013 pub struct Sequence<A>
1014 where
1015 A: SignalVec,
1016 {
1017 #[pin]
1018 signal: A,
1019 sequence: u64,
1020 }
1021}
1022
1023impl<A> Signal for Sequence<A>
1024where
1025 A: SignalVec,
1026{
1027 type Item = u64;
1028
1029 fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
1030 let mut this = self.project();
1031
1032 let mut changed = false;
1033
1034 let done = loop {
1035 break match this.signal.as_mut().poll_vec_change(cx) {
1036 Poll::Ready(None) => true,
1037 Poll::Ready(Some(_)) => {
1038 *this.sequence += 1;
1039 changed = true;
1040 continue;
1041 }
1042 Poll::Pending => false,
1043 };
1044 };
1045
1046 if changed {
1047 Poll::Ready(Some(*this.sequence))
1048 } else if done {
1049 Poll::Ready(None)
1050 } else {
1051 Poll::Pending
1052 }
1053 }
1054}
1055
1056#[cfg(test)]
1057mod test {
1058 use futures_signals::signal_vec::MutableVec;
1059
1060 use crate::MutableVecExt;
1061
1062 #[test]
1063 fn replace_keyed() {
1064 let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1065 assert_eq!(vec.replace_keyed(|(k, _)| *k, [("b", 20), ("d", 4)]), true);
1066 assert_eq!(
1067 vec.lock_ref().as_slice(),
1068 &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1069 );
1070 }
1071
1072 #[test]
1073 fn replace_keyed_cloned() {
1074 let vec = MutableVec::new_with_values(vec![("a", 1), ("b", 2), ("c", 3)]);
1075 assert_eq!(
1076 vec.replace_keyed_cloned(|(k, _)| *k, [("b", 20), ("d", 4)]),
1077 true
1078 );
1079 assert_eq!(
1080 vec.lock_ref().as_slice(),
1081 &[("a", 1), ("b", 20), ("c", 3), ("d", 4)]
1082 );
1083 }
1084}