1pub mod read {
5 use crate::{
6 computed::{ArcMemo, Memo},
7 graph::untrack,
8 owner::{
9 ArcStoredValue, ArenaItem, FromLocal, LocalStorage, Storage,
10 SyncStorage,
11 },
12 signal::{
13 guards::{Mapped, Plain, ReadGuard},
14 ArcMappedSignal, ArcReadSignal, ArcRwSignal, MappedSignal,
15 ReadSignal, RwSignal,
16 },
17 traits::{
18 DefinedAt, Dispose, Get, Read, ReadUntracked, ReadValue, Track,
19 },
20 unwrap_signal,
21 };
22 use send_wrapper::SendWrapper;
23 use std::{
24 borrow::Borrow,
25 fmt::Display,
26 ops::Deref,
27 panic::Location,
28 sync::{Arc, RwLock},
29 };
30
31 pub enum SignalTypes<T, S = SyncStorage>
33 where
34 S: Storage<T>,
35 {
36 ReadSignal(ArcReadSignal<T>),
38 Memo(ArcMemo<T, S>),
40 DerivedSignal(Arc<dyn Fn() -> T + Send + Sync>),
42 Stored(ArcStoredValue<T>),
44 }
45
46 impl<T, S> Clone for SignalTypes<T, S>
47 where
48 S: Storage<T>,
49 {
50 fn clone(&self) -> Self {
51 match self {
52 Self::ReadSignal(arg0) => Self::ReadSignal(arg0.clone()),
53 Self::Memo(arg0) => Self::Memo(arg0.clone()),
54 Self::DerivedSignal(arg0) => Self::DerivedSignal(arg0.clone()),
55 Self::Stored(arg0) => Self::Stored(arg0.clone()),
56 }
57 }
58 }
59
60 impl<T, S> core::fmt::Debug for SignalTypes<T, S>
61 where
62 S: Storage<T>,
63 {
64 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65 match self {
66 Self::ReadSignal(arg0) => {
67 f.debug_tuple("ReadSignal").field(arg0).finish()
68 }
69 Self::Memo(arg0) => f.debug_tuple("Memo").field(arg0).finish(),
70 Self::DerivedSignal(_) => {
71 f.debug_tuple("DerivedSignal").finish()
72 }
73 Self::Stored(arg0) => {
74 f.debug_tuple("Static").field(arg0).finish()
75 }
76 }
77 }
78 }
79
80 impl<T, S> PartialEq for SignalTypes<T, S>
81 where
82 S: Storage<T>,
83 {
84 fn eq(&self, other: &Self) -> bool {
85 match (self, other) {
86 (Self::ReadSignal(l0), Self::ReadSignal(r0)) => l0 == r0,
87 (Self::Memo(l0), Self::Memo(r0)) => l0 == r0,
88 (Self::DerivedSignal(l0), Self::DerivedSignal(r0)) => {
89 std::ptr::eq(l0, r0)
90 }
91 _ => false,
92 }
93 }
94 }
95
96 pub struct ArcSignal<T: 'static, S = SyncStorage>
122 where
123 S: Storage<T>,
124 {
125 #[cfg(any(debug_assertions, leptos_debuginfo))]
126 defined_at: &'static Location<'static>,
127 inner: SignalTypes<T, S>,
128 }
129
130 impl<T, S> Clone for ArcSignal<T, S>
131 where
132 S: Storage<T>,
133 {
134 fn clone(&self) -> Self {
135 Self {
136 #[cfg(any(debug_assertions, leptos_debuginfo))]
137 defined_at: self.defined_at,
138 inner: self.inner.clone(),
139 }
140 }
141 }
142
143 impl<T, S> core::fmt::Debug for ArcSignal<T, S>
144 where
145 S: Storage<T>,
146 {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 let mut s = f.debug_struct("ArcSignal");
149 s.field("inner", &self.inner);
150 #[cfg(any(debug_assertions, leptos_debuginfo))]
151 s.field("defined_at", &self.defined_at);
152 s.finish()
153 }
154 }
155
156 impl<T, S> Eq for ArcSignal<T, S> where S: Storage<T> {}
157
158 impl<T, S> PartialEq for ArcSignal<T, S>
159 where
160 S: Storage<T>,
161 {
162 fn eq(&self, other: &Self) -> bool {
163 self.inner == other.inner
164 }
165 }
166
167 impl<T> ArcSignal<T, SyncStorage>
168 where
169 SyncStorage: Storage<T>,
170 {
171 #[track_caller]
192 pub fn derive(
193 derived_signal: impl Fn() -> T + Send + Sync + 'static,
194 ) -> Self {
195 #[cfg(feature = "tracing")]
196 let span = ::tracing::Span::current();
197
198 let derived_signal = move || {
199 #[cfg(feature = "tracing")]
200 let _guard = span.enter();
201 derived_signal()
202 };
203
204 Self {
205 inner: SignalTypes::DerivedSignal(Arc::new(derived_signal)),
206 #[cfg(any(debug_assertions, leptos_debuginfo))]
207 defined_at: std::panic::Location::caller(),
208 }
209 }
210
211 #[track_caller]
213 pub fn stored(value: T) -> Self {
214 Self {
215 inner: SignalTypes::Stored(ArcStoredValue::new(value)),
216 #[cfg(any(debug_assertions, leptos_debuginfo))]
217 defined_at: std::panic::Location::caller(),
218 }
219 }
220 }
221
222 impl<T> ArcSignal<T, LocalStorage>
223 where
224 T: 'static,
225 {
226 #[track_caller]
228 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
229 Signal::derive_local(derived_signal).into()
230 }
231
232 #[track_caller]
235 pub fn stored_local(value: T) -> Self {
236 Signal::stored_local(value).into()
237 }
238 }
239
240 impl<T> Default for ArcSignal<T, SyncStorage>
241 where
242 T: Default + Send + Sync + 'static,
243 {
244 fn default() -> Self {
245 Self::stored(Default::default())
246 }
247 }
248
249 impl<T: Send + Sync> From<ArcReadSignal<T>> for ArcSignal<T, SyncStorage> {
250 #[track_caller]
251 fn from(value: ArcReadSignal<T>) -> Self {
252 Self {
253 inner: SignalTypes::ReadSignal(value),
254 #[cfg(any(debug_assertions, leptos_debuginfo))]
255 defined_at: std::panic::Location::caller(),
256 }
257 }
258 }
259
260 impl<T: Send + Sync> From<ArcRwSignal<T>> for ArcSignal<T, SyncStorage> {
261 #[track_caller]
262 fn from(value: ArcRwSignal<T>) -> Self {
263 Self {
264 inner: SignalTypes::ReadSignal(value.read_only()),
265 #[cfg(any(debug_assertions, leptos_debuginfo))]
266 defined_at: std::panic::Location::caller(),
267 }
268 }
269 }
270
271 impl<T, S> From<ArcMemo<T, S>> for ArcSignal<T, S>
272 where
273 S: Storage<T>,
274 {
275 #[track_caller]
276 fn from(value: ArcMemo<T, S>) -> Self {
277 Self {
278 inner: SignalTypes::Memo(value),
279 #[cfg(any(debug_assertions, leptos_debuginfo))]
280 defined_at: std::panic::Location::caller(),
281 }
282 }
283 }
284
285 impl<T, S> DefinedAt for ArcSignal<T, S>
286 where
287 S: Storage<T>,
288 {
289 fn defined_at(&self) -> Option<&'static Location<'static>> {
290 #[cfg(any(debug_assertions, leptos_debuginfo))]
291 {
292 Some(self.defined_at)
293 }
294 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
295 {
296 None
297 }
298 }
299 }
300
301 impl<T, S> Track for ArcSignal<T, S>
302 where
303 S: Storage<T>,
304 {
305 fn track(&self) {
306 match &self.inner {
307 SignalTypes::ReadSignal(i) => {
308 i.track();
309 }
310 SignalTypes::Memo(i) => {
311 i.track();
312 }
313 SignalTypes::DerivedSignal(i) => {
314 i();
315 }
316 SignalTypes::Stored(_) => {}
318 }
319 }
320 }
321
322 impl<T, S> ReadUntracked for ArcSignal<T, S>
323 where
324 S: Storage<T>,
325 {
326 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
327
328 fn try_read_untracked(&self) -> Option<Self::Value> {
329 match &self.inner {
330 SignalTypes::ReadSignal(i) => {
331 i.try_read_untracked().map(SignalReadGuard::Read)
332 }
333 SignalTypes::Memo(i) => {
334 i.try_read_untracked().map(SignalReadGuard::Memo)
335 }
336 SignalTypes::DerivedSignal(i) => {
337 Some(SignalReadGuard::Owned(untrack(|| i())))
338 }
339 SignalTypes::Stored(i) => {
340 i.try_read_value().map(SignalReadGuard::Read)
341 }
342 }
343 .map(ReadGuard::new)
344 }
345
346 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
349 Some(
350 match &self.inner {
351 SignalTypes::ReadSignal(i) => {
352 i.try_read().map(SignalReadGuard::Read)
353 }
354 SignalTypes::Memo(i) => {
355 i.try_read().map(SignalReadGuard::Memo)
356 }
357 SignalTypes::DerivedSignal(i) => {
358 Some(SignalReadGuard::Owned(i()))
359 }
360 SignalTypes::Stored(i) => {
361 i.try_read_value().map(SignalReadGuard::Read)
362 }
363 }
364 .map(ReadGuard::new),
365 )
366 }
367 }
368
369 pub struct Signal<T, S = SyncStorage>
395 where
396 S: Storage<T>,
397 {
398 #[cfg(any(debug_assertions, leptos_debuginfo))]
399 defined_at: &'static Location<'static>,
400 inner: ArenaItem<SignalTypes<T, S>, S>,
401 }
402
403 impl<T, S> Dispose for Signal<T, S>
404 where
405 S: Storage<T>,
406 {
407 fn dispose(self) {
408 self.inner.dispose()
409 }
410 }
411
412 impl<T, S> Clone for Signal<T, S>
413 where
414 S: Storage<T>,
415 {
416 fn clone(&self) -> Self {
417 *self
418 }
419 }
420
421 impl<T, S> Copy for Signal<T, S> where S: Storage<T> {}
422
423 impl<T, S> core::fmt::Debug for Signal<T, S>
424 where
425 S: std::fmt::Debug + Storage<T>,
426 {
427 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
428 let mut s = f.debug_struct("Signal");
429 s.field("inner", &self.inner);
430 #[cfg(any(debug_assertions, leptos_debuginfo))]
431 s.field("defined_at", &self.defined_at);
432 s.finish()
433 }
434 }
435
436 impl<T, S> Eq for Signal<T, S> where S: Storage<T> {}
437
438 impl<T, S> PartialEq for Signal<T, S>
439 where
440 S: Storage<T>,
441 {
442 fn eq(&self, other: &Self) -> bool {
443 self.inner == other.inner
444 }
445 }
446
447 impl<T, S> DefinedAt for Signal<T, S>
448 where
449 S: Storage<T>,
450 {
451 fn defined_at(&self) -> Option<&'static Location<'static>> {
452 #[cfg(any(debug_assertions, leptos_debuginfo))]
453 {
454 Some(self.defined_at)
455 }
456 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
457 {
458 None
459 }
460 }
461 }
462
463 impl<T, S> Track for Signal<T, S>
464 where
465 T: 'static,
466 S: Storage<T> + Storage<SignalTypes<T, S>>,
467 {
468 fn track(&self) {
469 let inner = self
470 .inner
471 .try_with_value(Clone::clone)
474 .unwrap_or_else(unwrap_signal!(self));
475 match inner {
476 SignalTypes::ReadSignal(i) => {
477 i.track();
478 }
479 SignalTypes::Memo(i) => {
480 i.track();
481 }
482 SignalTypes::DerivedSignal(i) => {
483 i();
484 }
485 SignalTypes::Stored(_) => {}
487 }
488 }
489 }
490
491 impl<T, S> ReadUntracked for Signal<T, S>
492 where
493 T: 'static,
494 S: Storage<SignalTypes<T, S>> + Storage<T>,
495 {
496 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
497
498 fn try_read_untracked(&self) -> Option<Self::Value> {
499 self.inner
500 .try_with_value(Clone::clone)
503 .and_then(|inner| {
504 match &inner {
505 SignalTypes::ReadSignal(i) => {
506 i.try_read_untracked().map(SignalReadGuard::Read)
507 }
508 SignalTypes::Memo(i) => {
509 i.try_read_untracked().map(SignalReadGuard::Memo)
510 }
511 SignalTypes::DerivedSignal(i) => {
512 Some(SignalReadGuard::Owned(untrack(|| i())))
513 }
514 SignalTypes::Stored(i) => {
515 i.try_read_value().map(SignalReadGuard::Read)
516 }
517 }
518 .map(ReadGuard::new)
519 })
520 }
521
522 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
525 Some(
526 self.inner
527 .try_with_value(Clone::clone)
530 .and_then(|inner| {
531 match &inner {
532 SignalTypes::ReadSignal(i) => {
533 i.try_read().map(SignalReadGuard::Read)
534 }
535 SignalTypes::Memo(i) => {
536 i.try_read().map(SignalReadGuard::Memo)
537 }
538 SignalTypes::DerivedSignal(i) => {
539 Some(SignalReadGuard::Owned(i()))
540 }
541 SignalTypes::Stored(i) => {
542 i.try_read_value().map(SignalReadGuard::Read)
543 }
544 }
545 .map(ReadGuard::new)
546 }),
547 )
548 }
549 }
550
551 impl<T> Signal<T>
552 where
553 T: Send + Sync + 'static,
554 {
555 #[track_caller]
573 pub fn derive(
574 derived_signal: impl Fn() -> T + Send + Sync + 'static,
575 ) -> Self {
576 #[cfg(feature = "tracing")]
577 let span = ::tracing::Span::current();
578
579 let derived_signal = move || {
580 #[cfg(feature = "tracing")]
581 let _guard = span.enter();
582 derived_signal()
583 };
584
585 Self {
586 inner: ArenaItem::new_with_storage(SignalTypes::DerivedSignal(
587 Arc::new(derived_signal),
588 )),
589 #[cfg(any(debug_assertions, leptos_debuginfo))]
590 defined_at: std::panic::Location::caller(),
591 }
592 }
593
594 #[track_caller]
596 pub fn stored(value: T) -> Self {
597 Self {
598 inner: ArenaItem::new_with_storage(SignalTypes::Stored(
599 ArcStoredValue::new(value),
600 )),
601 #[cfg(any(debug_assertions, leptos_debuginfo))]
602 defined_at: std::panic::Location::caller(),
603 }
604 }
605 }
606
607 impl<T> Signal<T, LocalStorage>
608 where
609 T: 'static,
610 {
611 #[track_caller]
613 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
614 let derived_signal = SendWrapper::new(derived_signal);
615 #[cfg(feature = "tracing")]
616 let span = ::tracing::Span::current();
617
618 let derived_signal = move || {
619 #[cfg(feature = "tracing")]
620 let _guard = span.enter();
621 derived_signal()
622 };
623
624 Self {
625 inner: ArenaItem::new_local(SignalTypes::DerivedSignal(
626 Arc::new(derived_signal),
627 )),
628 #[cfg(any(debug_assertions, leptos_debuginfo))]
629 defined_at: std::panic::Location::caller(),
630 }
631 }
632
633 #[track_caller]
636 pub fn stored_local(value: T) -> Self {
637 Self {
638 inner: ArenaItem::new_local(SignalTypes::Stored(
639 ArcStoredValue::new(value),
640 )),
641 #[cfg(any(debug_assertions, leptos_debuginfo))]
642 defined_at: std::panic::Location::caller(),
643 }
644 }
645 }
646
647 impl<T> Default for Signal<T>
648 where
649 T: Send + Sync + Default + 'static,
650 {
651 fn default() -> Self {
652 Self::stored(Default::default())
653 }
654 }
655
656 impl<T> Default for Signal<T, LocalStorage>
657 where
658 T: Default + 'static,
659 {
660 fn default() -> Self {
661 Self::stored_local(Default::default())
662 }
663 }
664
665 impl<T: Send + Sync + 'static> From<T> for ArcSignal<T, SyncStorage> {
666 #[track_caller]
667 fn from(value: T) -> Self {
668 ArcSignal::stored(value)
669 }
670 }
671
672 impl<T> From<T> for Signal<T>
673 where
674 T: Send + Sync + 'static,
675 {
676 #[track_caller]
677 fn from(value: T) -> Self {
678 Self::stored(value)
679 }
680 }
681
682 impl<T> From<T> for Signal<T, LocalStorage>
683 where
684 T: 'static,
685 {
686 #[track_caller]
687 fn from(value: T) -> Self {
688 Self::stored_local(value)
689 }
690 }
691
692 impl<T> From<ArcSignal<T, SyncStorage>> for Signal<T>
693 where
694 T: Send + Sync + 'static,
695 {
696 #[track_caller]
697 fn from(value: ArcSignal<T, SyncStorage>) -> Self {
698 Signal {
699 #[cfg(any(debug_assertions, leptos_debuginfo))]
700 defined_at: Location::caller(),
701 inner: ArenaItem::new(value.inner),
702 }
703 }
704 }
705
706 impl<T> FromLocal<ArcSignal<T, LocalStorage>> for Signal<T, LocalStorage>
707 where
708 T: 'static,
709 {
710 #[track_caller]
711 fn from_local(value: ArcSignal<T, LocalStorage>) -> Self {
712 Signal {
713 #[cfg(any(debug_assertions, leptos_debuginfo))]
714 defined_at: Location::caller(),
715 inner: ArenaItem::new_local(value.inner),
716 }
717 }
718 }
719
720 impl<T, S> From<Signal<T, S>> for ArcSignal<T, S>
721 where
722 S: Storage<SignalTypes<T, S>> + Storage<T>,
723 {
724 #[track_caller]
725 fn from(value: Signal<T, S>) -> Self {
726 ArcSignal {
727 #[cfg(any(debug_assertions, leptos_debuginfo))]
728 defined_at: Location::caller(),
729 inner: value
730 .inner
731 .try_get_value()
732 .unwrap_or_else(unwrap_signal!(value)),
733 }
734 }
735 }
736
737 impl<T> From<ReadSignal<T>> for Signal<T>
738 where
739 T: Send + Sync + 'static,
740 {
741 #[track_caller]
742 fn from(value: ReadSignal<T>) -> Self {
743 Self {
744 inner: ArenaItem::new(SignalTypes::ReadSignal(value.into())),
745 #[cfg(any(debug_assertions, leptos_debuginfo))]
746 defined_at: std::panic::Location::caller(),
747 }
748 }
749 }
750
751 impl<T> From<ReadSignal<T, LocalStorage>> for Signal<T, LocalStorage>
752 where
753 T: 'static,
754 {
755 #[track_caller]
756 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
757 Self {
758 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
759 value.into(),
760 )),
761 #[cfg(any(debug_assertions, leptos_debuginfo))]
762 defined_at: std::panic::Location::caller(),
763 }
764 }
765 }
766
767 impl<T> From<ArcReadSignal<T>> for Signal<T>
768 where
769 T: Send + Sync + 'static,
770 {
771 #[track_caller]
772 fn from(value: ArcReadSignal<T>) -> Self {
773 Self {
774 inner: ArenaItem::new(SignalTypes::ReadSignal(value)),
775 #[cfg(any(debug_assertions, leptos_debuginfo))]
776 defined_at: std::panic::Location::caller(),
777 }
778 }
779 }
780
781 impl<T> From<ArcReadSignal<T>> for Signal<T, LocalStorage>
782 where
783 T: Send + Sync + 'static,
784 {
785 #[track_caller]
786 fn from(value: ArcReadSignal<T>) -> Self {
787 Self {
788 inner: ArenaItem::new_local(SignalTypes::ReadSignal(value)),
789 #[cfg(any(debug_assertions, leptos_debuginfo))]
790 defined_at: std::panic::Location::caller(),
791 }
792 }
793 }
794
795 impl<T> From<RwSignal<T>> for Signal<T>
796 where
797 T: Send + Sync + 'static,
798 {
799 #[track_caller]
800 fn from(value: RwSignal<T>) -> Self {
801 Self {
802 inner: ArenaItem::new(SignalTypes::ReadSignal(
803 value.read_only().into(),
804 )),
805 #[cfg(any(debug_assertions, leptos_debuginfo))]
806 defined_at: std::panic::Location::caller(),
807 }
808 }
809 }
810
811 impl<T> From<MappedSignal<T>> for Signal<T>
812 where
813 T: Clone + Send + Sync + 'static,
814 {
815 #[track_caller]
816 fn from(value: MappedSignal<T>) -> Self {
817 Self::derive(move || value.get())
818 }
819 }
820
821 impl<T> From<RwSignal<T, LocalStorage>> for Signal<T, LocalStorage>
822 where
823 T: 'static,
824 {
825 #[track_caller]
826 fn from(value: RwSignal<T, LocalStorage>) -> Self {
827 Self {
828 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
829 value.read_only().into(),
830 )),
831 #[cfg(any(debug_assertions, leptos_debuginfo))]
832 defined_at: std::panic::Location::caller(),
833 }
834 }
835 }
836
837 impl<T> From<ArcRwSignal<T>> for Signal<T>
838 where
839 T: Send + Sync + 'static,
840 {
841 #[track_caller]
842 fn from(value: ArcRwSignal<T>) -> Self {
843 Self {
844 inner: ArenaItem::new(SignalTypes::ReadSignal(
845 value.read_only(),
846 )),
847 #[cfg(any(debug_assertions, leptos_debuginfo))]
848 defined_at: std::panic::Location::caller(),
849 }
850 }
851 }
852
853 impl<T> From<ArcMappedSignal<T>> for Signal<T>
854 where
855 T: Clone + Send + Sync + 'static,
856 {
857 #[track_caller]
858 fn from(value: ArcMappedSignal<T>) -> Self {
859 MappedSignal::from(value).into()
860 }
861 }
862
863 impl<T> From<ArcRwSignal<T>> for Signal<T, LocalStorage>
864 where
865 T: Send + Sync + 'static,
866 {
867 #[track_caller]
868 fn from(value: ArcRwSignal<T>) -> Self {
869 Self {
870 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
871 value.read_only(),
872 )),
873 #[cfg(any(debug_assertions, leptos_debuginfo))]
874 defined_at: std::panic::Location::caller(),
875 }
876 }
877 }
878
879 impl<T> From<Memo<T>> for Signal<T>
880 where
881 T: Send + Sync + 'static,
882 {
883 #[track_caller]
884 fn from(value: Memo<T>) -> Self {
885 Self {
886 inner: ArenaItem::new(SignalTypes::Memo(value.into())),
887 #[cfg(any(debug_assertions, leptos_debuginfo))]
888 defined_at: std::panic::Location::caller(),
889 }
890 }
891 }
892
893 impl<T> From<Memo<T, LocalStorage>> for Signal<T, LocalStorage>
894 where
895 T: 'static,
896 {
897 #[track_caller]
898 fn from(value: Memo<T, LocalStorage>) -> Self {
899 Self {
900 inner: ArenaItem::new_local(SignalTypes::Memo(value.into())),
901 #[cfg(any(debug_assertions, leptos_debuginfo))]
902 defined_at: std::panic::Location::caller(),
903 }
904 }
905 }
906
907 impl<T> From<ArcMemo<T>> for Signal<T>
908 where
909 T: Send + Sync + 'static,
910 {
911 #[track_caller]
912 fn from(value: ArcMemo<T>) -> Self {
913 Self {
914 inner: ArenaItem::new(SignalTypes::Memo(value)),
915 #[cfg(any(debug_assertions, leptos_debuginfo))]
916 defined_at: std::panic::Location::caller(),
917 }
918 }
919 }
920
921 impl<T> From<ArcMemo<T, LocalStorage>> for Signal<T, LocalStorage>
922 where
923 T: Send + Sync + 'static,
924 {
925 #[track_caller]
926 fn from(value: ArcMemo<T, LocalStorage>) -> Self {
927 Self {
928 inner: ArenaItem::new_local(SignalTypes::Memo(value)),
929 #[cfg(any(debug_assertions, leptos_debuginfo))]
930 defined_at: std::panic::Location::caller(),
931 }
932 }
933 }
934
935 impl<T> From<T> for Signal<Option<T>>
936 where
937 T: Send + Sync + 'static,
938 {
939 #[track_caller]
940 fn from(value: T) -> Self {
941 Signal::stored(Some(value))
942 }
943 }
944
945 impl<T> From<T> for Signal<Option<T>, LocalStorage>
946 where
947 T: 'static,
948 {
949 #[track_caller]
950 fn from(value: T) -> Self {
951 Signal::stored_local(Some(value))
952 }
953 }
954
955 impl<T> From<Signal<T>> for Signal<Option<T>>
956 where
957 T: Clone + Send + Sync + 'static,
958 {
959 #[track_caller]
960 fn from(value: Signal<T>) -> Self {
961 Signal::derive(move || Some(value.get()))
962 }
963 }
964
965 impl<T> From<Signal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
966 where
967 T: Clone + 'static,
968 {
969 #[track_caller]
970 fn from(value: Signal<T, LocalStorage>) -> Self {
971 Signal::derive_local(move || Some(value.get()))
972 }
973 }
974
975 impl From<&str> for Signal<String> {
976 #[track_caller]
977 fn from(value: &str) -> Self {
978 Signal::stored(value.to_string())
979 }
980 }
981
982 impl From<&str> for Signal<String, LocalStorage> {
983 #[track_caller]
984 fn from(value: &str) -> Self {
985 Signal::stored_local(value.to_string())
986 }
987 }
988
989 impl From<&str> for Signal<Option<String>> {
990 #[track_caller]
991 fn from(value: &str) -> Self {
992 Signal::stored(Some(value.to_string()))
993 }
994 }
995
996 impl From<&str> for Signal<Option<String>, LocalStorage> {
997 #[track_caller]
998 fn from(value: &str) -> Self {
999 Signal::stored_local(Some(value.to_string()))
1000 }
1001 }
1002
1003 impl From<Signal<&'static str>> for Signal<String> {
1004 #[track_caller]
1005 fn from(value: Signal<&'static str>) -> Self {
1006 Signal::derive(move || value.read().to_string())
1007 }
1008 }
1009
1010 impl From<Signal<&'static str>> for Signal<String, LocalStorage> {
1011 #[track_caller]
1012 fn from(value: Signal<&'static str>) -> Self {
1013 Signal::derive_local(move || value.read().to_string())
1014 }
1015 }
1016
1017 impl From<Signal<&'static str>> for Signal<Option<String>> {
1018 #[track_caller]
1019 fn from(value: Signal<&'static str>) -> Self {
1020 Signal::derive(move || Some(value.read().to_string()))
1021 }
1022 }
1023
1024 impl From<Signal<&'static str>> for Signal<Option<String>, LocalStorage> {
1025 #[track_caller]
1026 fn from(value: Signal<&'static str>) -> Self {
1027 Signal::derive_local(move || Some(value.read().to_string()))
1028 }
1029 }
1030
1031 impl From<Signal<Option<&'static str>>> for Signal<Option<String>> {
1032 #[track_caller]
1033 fn from(value: Signal<Option<&'static str>>) -> Self {
1034 Signal::derive(move || value.read().map(str::to_string))
1035 }
1036 }
1037
1038 impl From<Signal<Option<&'static str>>>
1039 for Signal<Option<String>, LocalStorage>
1040 {
1041 #[track_caller]
1042 fn from(value: Signal<Option<&'static str>>) -> Self {
1043 Signal::derive_local(move || value.read().map(str::to_string))
1044 }
1045 }
1046
1047 #[allow(deprecated)]
1048 impl<T> From<MaybeSignal<T>> for Signal<T>
1049 where
1050 T: Send + Sync + 'static,
1051 {
1052 #[track_caller]
1053 fn from(value: MaybeSignal<T>) -> Self {
1054 match value {
1055 MaybeSignal::Static(value) => Signal::stored(value),
1056 MaybeSignal::Dynamic(signal) => signal,
1057 }
1058 }
1059 }
1060
1061 #[allow(deprecated)]
1062 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<T, LocalStorage>
1063 where
1064 T: Send + Sync + 'static,
1065 {
1066 #[track_caller]
1067 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1068 match value {
1069 MaybeSignal::Static(value) => Signal::stored_local(value),
1070 MaybeSignal::Dynamic(signal) => signal,
1071 }
1072 }
1073 }
1074
1075 #[allow(deprecated)]
1076 impl<T> From<MaybeSignal<T>> for Signal<Option<T>>
1077 where
1078 T: Clone + Send + Sync + 'static,
1079 {
1080 #[track_caller]
1081 fn from(value: MaybeSignal<T>) -> Self {
1082 match value {
1083 MaybeSignal::Static(value) => Signal::stored(Some(value)),
1084 MaybeSignal::Dynamic(signal) => {
1085 Signal::derive(move || Some(signal.get()))
1086 }
1087 }
1088 }
1089 }
1090
1091 #[allow(deprecated)]
1092 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
1093 where
1094 T: Clone + Send + Sync + 'static,
1095 {
1096 #[track_caller]
1097 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1098 match value {
1099 MaybeSignal::Static(value) => Signal::stored_local(Some(value)),
1100 MaybeSignal::Dynamic(signal) => {
1101 Signal::derive_local(move || Some(signal.get()))
1102 }
1103 }
1104 }
1105 }
1106
1107 impl<T> From<MaybeProp<T>> for Option<Signal<Option<T>>>
1108 where
1109 T: Send + Sync + 'static,
1110 {
1111 #[track_caller]
1112 fn from(value: MaybeProp<T>) -> Self {
1113 value.0
1114 }
1115 }
1116
1117 impl<T> From<MaybeProp<T, LocalStorage>>
1118 for Option<Signal<Option<T>, LocalStorage>>
1119 where
1120 T: Send + Sync + 'static,
1121 {
1122 #[track_caller]
1123 fn from(value: MaybeProp<T, LocalStorage>) -> Self {
1124 value.0
1125 }
1126 }
1127
1128 #[derive(Debug, PartialEq, Eq)]
1156 #[deprecated(
1157 since = "0.7.0-rc3",
1158 note = "`MaybeSignal<T>` is deprecated in favour of `Signal<T>` which \
1159 is `Copy`, now has a more efficient From<T> implementation \
1160 and other benefits in 0.7."
1161 )]
1162 pub enum MaybeSignal<T, S = SyncStorage>
1163 where
1164 T: 'static,
1165 S: Storage<T>,
1166 {
1167 Static(T),
1169 Dynamic(Signal<T, S>),
1171 }
1172
1173 #[allow(deprecated)]
1174 impl<T: Clone, S> Clone for MaybeSignal<T, S>
1175 where
1176 S: Storage<T>,
1177 {
1178 fn clone(&self) -> Self {
1179 match self {
1180 Self::Static(item) => Self::Static(item.clone()),
1181 Self::Dynamic(signal) => Self::Dynamic(*signal),
1182 }
1183 }
1184 }
1185
1186 #[allow(deprecated)]
1187 impl<T: Copy, S> Copy for MaybeSignal<T, S> where S: Storage<T> {}
1188
1189 #[allow(deprecated)]
1190 impl<T: Default, S> Default for MaybeSignal<T, S>
1191 where
1192 S: Storage<T>,
1193 {
1194 fn default() -> Self {
1195 Self::Static(Default::default())
1196 }
1197 }
1198
1199 #[allow(deprecated)]
1200 impl<T, S> DefinedAt for MaybeSignal<T, S>
1201 where
1202 S: Storage<T>,
1203 {
1204 fn defined_at(&self) -> Option<&'static Location<'static>> {
1205 None
1208 }
1209 }
1210
1211 #[allow(deprecated)]
1212 impl<T, S> Track for MaybeSignal<T, S>
1213 where
1214 S: Storage<T> + Storage<SignalTypes<T, S>>,
1215 {
1216 fn track(&self) {
1217 match self {
1218 Self::Static(_) => {}
1219 Self::Dynamic(signal) => signal.track(),
1220 }
1221 }
1222 }
1223
1224 #[allow(deprecated)]
1225 impl<T, S> ReadUntracked for MaybeSignal<T, S>
1226 where
1227 T: Clone,
1228 S: Storage<SignalTypes<T, S>> + Storage<T>,
1229 {
1230 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
1231
1232 fn try_read_untracked(&self) -> Option<Self::Value> {
1233 match self {
1234 Self::Static(t) => {
1235 Some(ReadGuard::new(SignalReadGuard::Owned(t.clone())))
1236 }
1237 Self::Dynamic(s) => s.try_read_untracked(),
1238 }
1239 }
1240
1241 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1242 match self {
1243 Self::Static(_) => None,
1244 Self::Dynamic(s) => s.custom_try_read(),
1245 }
1246 }
1247 }
1248
1249 #[allow(deprecated)]
1250 impl<T> MaybeSignal<T>
1251 where
1252 T: Send + Sync,
1253 {
1254 pub fn derive(
1257 derived_signal: impl Fn() -> T + Send + Sync + 'static,
1258 ) -> Self {
1259 Self::Dynamic(Signal::derive(derived_signal))
1260 }
1261 }
1262
1263 #[allow(deprecated)]
1264 impl<T> MaybeSignal<T, LocalStorage> {
1265 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
1268 Self::Dynamic(Signal::derive_local(derived_signal))
1269 }
1270 }
1271
1272 #[allow(deprecated)]
1273 impl<T> From<T> for MaybeSignal<T, SyncStorage>
1274 where
1275 SyncStorage: Storage<T>,
1276 {
1277 fn from(value: T) -> Self {
1278 Self::Static(value)
1279 }
1280 }
1281
1282 #[allow(deprecated)]
1283 impl<T> FromLocal<T> for MaybeSignal<T, LocalStorage>
1284 where
1285 LocalStorage: Storage<T>,
1286 {
1287 fn from_local(value: T) -> Self {
1288 Self::Static(value)
1289 }
1290 }
1291
1292 #[allow(deprecated)]
1293 impl<T> From<ReadSignal<T>> for MaybeSignal<T>
1294 where
1295 T: Send + Sync,
1296 {
1297 fn from(value: ReadSignal<T>) -> Self {
1298 Self::Dynamic(value.into())
1299 }
1300 }
1301
1302 #[allow(deprecated)]
1303 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1304 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1305 Self::Dynamic(value.into())
1306 }
1307 }
1308
1309 #[allow(deprecated)]
1310 impl<T> From<RwSignal<T>> for MaybeSignal<T>
1311 where
1312 T: Send + Sync,
1313 {
1314 fn from(value: RwSignal<T>) -> Self {
1315 Self::Dynamic(value.into())
1316 }
1317 }
1318
1319 #[allow(deprecated)]
1320 impl<T> From<RwSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1321 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1322 Self::Dynamic(value.into())
1323 }
1324 }
1325
1326 #[allow(deprecated)]
1327 impl<T> From<Memo<T>> for MaybeSignal<T>
1328 where
1329 T: Send + Sync,
1330 {
1331 fn from(value: Memo<T>) -> Self {
1332 Self::Dynamic(value.into())
1333 }
1334 }
1335
1336 #[allow(deprecated)]
1337 impl<T> From<Memo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1338 fn from(value: Memo<T, LocalStorage>) -> Self {
1339 Self::Dynamic(value.into())
1340 }
1341 }
1342
1343 #[allow(deprecated)]
1344 impl<T> From<ArcReadSignal<T>> for MaybeSignal<T>
1345 where
1346 T: Send + Sync,
1347 {
1348 fn from(value: ArcReadSignal<T>) -> Self {
1349 ReadSignal::from(value).into()
1350 }
1351 }
1352
1353 #[allow(deprecated)]
1354 impl<T> FromLocal<ArcReadSignal<T>> for MaybeSignal<T, LocalStorage> {
1355 fn from_local(value: ArcReadSignal<T>) -> Self {
1356 ReadSignal::from_local(value).into()
1357 }
1358 }
1359
1360 #[allow(deprecated)]
1361 impl<T> From<ArcRwSignal<T>> for MaybeSignal<T>
1362 where
1363 T: Send + Sync + 'static,
1364 {
1365 fn from(value: ArcRwSignal<T>) -> Self {
1366 RwSignal::from(value).into()
1367 }
1368 }
1369
1370 #[allow(deprecated)]
1371 impl<T> FromLocal<ArcRwSignal<T>> for MaybeSignal<T, LocalStorage>
1372 where
1373 T: 'static,
1374 {
1375 fn from_local(value: ArcRwSignal<T>) -> Self {
1376 RwSignal::from_local(value).into()
1377 }
1378 }
1379
1380 #[allow(deprecated)]
1381 impl<T> From<ArcMemo<T>> for MaybeSignal<T>
1382 where
1383 T: Send + Sync,
1384 {
1385 fn from(value: ArcMemo<T>) -> Self {
1386 Memo::from(value).into()
1387 }
1388 }
1389
1390 #[allow(deprecated)]
1391 impl<T> FromLocal<ArcMemo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1392 fn from_local(value: ArcMemo<T, LocalStorage>) -> Self {
1393 Memo::from_local(value).into()
1394 }
1395 }
1396
1397 #[allow(deprecated)]
1398 impl<T, S> From<Signal<T, S>> for MaybeSignal<T, S>
1399 where
1400 S: Storage<T>,
1401 {
1402 fn from(value: Signal<T, S>) -> Self {
1403 Self::Dynamic(value)
1404 }
1405 }
1406
1407 #[allow(deprecated)]
1408 impl<S> From<&str> for MaybeSignal<String, S>
1409 where
1410 S: Storage<String> + Storage<Arc<RwLock<String>>>,
1411 {
1412 fn from(value: &str) -> Self {
1413 Self::Static(value.to_string())
1414 }
1415 }
1416
1417 #[derive(Debug, PartialEq, Eq)]
1450 pub struct MaybeProp<T: 'static, S = SyncStorage>(
1451 pub(crate) Option<Signal<Option<T>, S>>,
1452 )
1453 where
1454 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>;
1455
1456 impl<T, S> Clone for MaybeProp<T, S>
1457 where
1458 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1459 {
1460 fn clone(&self) -> Self {
1461 *self
1462 }
1463 }
1464
1465 impl<T, S> Copy for MaybeProp<T, S> where
1466 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>
1467 {
1468 }
1469
1470 impl<T, S> Default for MaybeProp<T, S>
1471 where
1472 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1473 {
1474 fn default() -> Self {
1475 Self(None)
1476 }
1477 }
1478
1479 impl<T, S> DefinedAt for MaybeProp<T, S>
1480 where
1481 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1482 {
1483 fn defined_at(&self) -> Option<&'static Location<'static>> {
1484 None
1486 }
1487 }
1488
1489 impl<T, S> Track for MaybeProp<T, S>
1490 where
1491 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1492 {
1493 fn track(&self) {
1494 match &self.0 {
1495 None => {}
1496 Some(signal) => signal.track(),
1497 }
1498 }
1499 }
1500
1501 impl<T, S> ReadUntracked for MaybeProp<T, S>
1502 where
1503 T: Clone,
1504 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1505 {
1506 type Value = ReadGuard<Option<T>, SignalReadGuard<Option<T>, S>>;
1507
1508 fn try_read_untracked(&self) -> Option<Self::Value> {
1509 match &self.0 {
1510 None => Some(ReadGuard::new(SignalReadGuard::Owned(None))),
1511 Some(inner) => inner.try_read_untracked(),
1512 }
1513 }
1514
1515 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1516 match &self.0 {
1517 None => None,
1518 Some(inner) => inner.custom_try_read(),
1519 }
1520 }
1521 }
1522
1523 impl<T> MaybeProp<T>
1524 where
1525 T: Send + Sync,
1526 {
1527 pub fn derive(
1530 derived_signal: impl Fn() -> Option<T> + Send + Sync + 'static,
1531 ) -> Self {
1532 Self(Some(Signal::derive(derived_signal)))
1533 }
1534 }
1535
1536 impl<T> From<T> for MaybeProp<T>
1537 where
1538 T: Send + Sync,
1539 SyncStorage: Storage<Option<T>>,
1540 {
1541 fn from(value: T) -> Self {
1542 Self(Some(Signal::stored(Some(value))))
1543 }
1544 }
1545
1546 impl<T> From<Option<T>> for MaybeProp<T>
1547 where
1548 T: Send + Sync,
1549 SyncStorage: Storage<Option<T>>,
1550 {
1551 fn from(value: Option<T>) -> Self {
1552 Self(Some(Signal::stored(value)))
1553 }
1554 }
1555
1556 #[allow(deprecated)]
1557 impl<T> From<MaybeSignal<Option<T>>> for MaybeProp<T>
1558 where
1559 T: Send + Sync,
1560 SyncStorage: Storage<Option<T>>,
1561 {
1562 fn from(value: MaybeSignal<Option<T>>) -> Self {
1563 Self(Some(value.into()))
1564 }
1565 }
1566
1567 #[allow(deprecated)]
1568 impl<T> From<Option<MaybeSignal<Option<T>>>> for MaybeProp<T>
1569 where
1570 T: Send + Sync,
1571 SyncStorage: Storage<Option<T>>,
1572 {
1573 fn from(value: Option<MaybeSignal<Option<T>>>) -> Self {
1574 Self(value.map(Into::into))
1575 }
1576 }
1577
1578 impl<T> From<ReadSignal<Option<T>>> for MaybeProp<T>
1579 where
1580 T: Send + Sync,
1581 {
1582 fn from(value: ReadSignal<Option<T>>) -> Self {
1583 Self(Some(value.into()))
1584 }
1585 }
1586
1587 impl<T> From<RwSignal<Option<T>>> for MaybeProp<T>
1588 where
1589 T: Send + Sync,
1590 {
1591 fn from(value: RwSignal<Option<T>>) -> Self {
1592 Self(Some(value.into()))
1593 }
1594 }
1595
1596 impl<T> From<Memo<Option<T>>> for MaybeProp<T>
1597 where
1598 T: Send + Sync,
1599 {
1600 fn from(value: Memo<Option<T>>) -> Self {
1601 Self(Some(value.into()))
1602 }
1603 }
1604
1605 impl<T> From<Signal<Option<T>>> for MaybeProp<T>
1606 where
1607 T: Send + Sync,
1608 SyncStorage: Storage<Option<T>>,
1609 {
1610 fn from(value: Signal<Option<T>>) -> Self {
1611 Self(Some(value))
1612 }
1613 }
1614
1615 impl<T> From<ReadSignal<T>> for MaybeProp<T>
1616 where
1617 T: Send + Sync + Clone,
1618 {
1619 fn from(value: ReadSignal<T>) -> Self {
1620 Self(Some(Signal::derive(move || Some(value.get()))))
1621 }
1622 }
1623
1624 impl<T> From<RwSignal<T>> for MaybeProp<T>
1625 where
1626 T: Send + Sync + Clone,
1627 {
1628 fn from(value: RwSignal<T>) -> Self {
1629 Self(Some(Signal::derive(move || Some(value.get()))))
1630 }
1631 }
1632
1633 impl<T> From<Memo<T>> for MaybeProp<T>
1634 where
1635 T: Send + Sync + Clone,
1636 {
1637 fn from(value: Memo<T>) -> Self {
1638 Self(Some(Signal::derive(move || Some(value.get()))))
1639 }
1640 }
1641
1642 impl<T> From<Signal<T>> for MaybeProp<T>
1643 where
1644 T: Send + Sync + Clone,
1645 {
1646 fn from(value: Signal<T>) -> Self {
1647 Self(Some(Signal::derive(move || Some(value.get()))))
1648 }
1649 }
1650
1651 impl From<&str> for MaybeProp<String> {
1652 fn from(value: &str) -> Self {
1653 Self(Some(Signal::from(Some(value.to_string()))))
1654 }
1655 }
1656
1657 impl<T> MaybeProp<T, LocalStorage> {
1658 pub fn derive_local(
1661 derived_signal: impl Fn() -> Option<T> + 'static,
1662 ) -> Self {
1663 Self(Some(Signal::derive_local(derived_signal)))
1664 }
1665 }
1666
1667 impl<T> FromLocal<T> for MaybeProp<T, LocalStorage> {
1668 fn from_local(value: T) -> Self {
1669 Self(Some(Signal::stored_local(Some(value))))
1670 }
1671 }
1672
1673 impl<T> FromLocal<Option<T>> for MaybeProp<T, LocalStorage> {
1674 fn from_local(value: Option<T>) -> Self {
1675 Self(Some(Signal::stored_local(value)))
1676 }
1677 }
1678
1679 #[allow(deprecated)]
1680 impl<T> From<MaybeSignal<Option<T>, LocalStorage>>
1681 for MaybeProp<T, LocalStorage>
1682 where
1683 T: Send + Sync,
1684 {
1685 fn from(value: MaybeSignal<Option<T>, LocalStorage>) -> Self {
1686 Self(Some(value.into()))
1687 }
1688 }
1689
1690 #[allow(deprecated)]
1691 impl<T> From<Option<MaybeSignal<Option<T>, LocalStorage>>>
1692 for MaybeProp<T, LocalStorage>
1693 where
1694 T: Send + Sync,
1695 {
1696 fn from(value: Option<MaybeSignal<Option<T>, LocalStorage>>) -> Self {
1697 Self(value.map(Into::into))
1698 }
1699 }
1700
1701 impl<T> From<ReadSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1702 where
1703 T: Send + Sync,
1704 {
1705 fn from(value: ReadSignal<Option<T>, LocalStorage>) -> Self {
1706 Self(Some(value.into()))
1707 }
1708 }
1709
1710 impl<T> From<RwSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1711 where
1712 T: Send + Sync,
1713 {
1714 fn from(value: RwSignal<Option<T>, LocalStorage>) -> Self {
1715 Self(Some(value.into()))
1716 }
1717 }
1718
1719 impl<T> From<Memo<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1720 where
1721 T: Send + Sync,
1722 {
1723 fn from(value: Memo<Option<T>, LocalStorage>) -> Self {
1724 Self(Some(value.into()))
1725 }
1726 }
1727
1728 impl<T> From<Signal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage> {
1729 fn from(value: Signal<Option<T>, LocalStorage>) -> Self {
1730 Self(Some(value))
1731 }
1732 }
1733
1734 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1735 where
1736 T: Send + Sync + Clone,
1737 {
1738 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1739 Self(Some(Signal::derive_local(move || Some(value.get()))))
1740 }
1741 }
1742
1743 impl<T> From<RwSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1744 where
1745 T: Send + Sync + Clone,
1746 {
1747 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1748 Self(Some(Signal::derive_local(move || Some(value.get()))))
1749 }
1750 }
1751
1752 impl<T> From<Memo<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1753 where
1754 T: Send + Sync + Clone,
1755 {
1756 fn from(value: Memo<T, LocalStorage>) -> Self {
1757 Self(Some(Signal::derive_local(move || Some(value.get()))))
1758 }
1759 }
1760
1761 impl<T> From<Signal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1762 where
1763 T: Send + Sync + Clone,
1764 {
1765 fn from(value: Signal<T, LocalStorage>) -> Self {
1766 Self(Some(Signal::derive_local(move || Some(value.get()))))
1767 }
1768 }
1769
1770 impl From<&str> for MaybeProp<String, LocalStorage> {
1771 fn from(value: &str) -> Self {
1772 Self(Some(Signal::stored_local(Some(value.to_string()))))
1773 }
1774 }
1775
1776 pub enum SignalReadGuard<T: 'static, S: Storage<T>> {
1778 Read(ReadGuard<T, Plain<T>>),
1780 #[allow(clippy::type_complexity)]
1781 Memo(
1783 ReadGuard<T, Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>>,
1784 ),
1785 Owned(T),
1787 }
1788
1789 impl<T: 'static + std::fmt::Debug, S: Storage<T> + std::fmt::Debug>
1790 std::fmt::Debug for SignalReadGuard<T, S>
1791 where
1792 <S as Storage<T>>::Wrapped: std::fmt::Debug,
1793 {
1794 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1795 match self {
1796 Self::Read(arg0) => f.debug_tuple("Read").field(arg0).finish(),
1797 Self::Memo(arg0) => f.debug_tuple("Memo").field(arg0).finish(),
1798 Self::Owned(arg0) => {
1799 f.debug_tuple("Owned").field(arg0).finish()
1800 }
1801 }
1802 }
1803 }
1804
1805 impl<T, S> Clone for SignalReadGuard<T, S>
1806 where
1807 S: Storage<T>,
1808 T: Clone,
1809 Plain<T>: Clone,
1810 Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>: Clone,
1811 {
1812 fn clone(&self) -> Self {
1813 match self {
1814 SignalReadGuard::Read(i) => SignalReadGuard::Read(i.clone()),
1815 SignalReadGuard::Memo(i) => SignalReadGuard::Memo(i.clone()),
1816 SignalReadGuard::Owned(i) => SignalReadGuard::Owned(i.clone()),
1817 }
1818 }
1819 }
1820
1821 impl<T, S> Deref for SignalReadGuard<T, S>
1822 where
1823 S: Storage<T>,
1824 {
1825 type Target = T;
1826 fn deref(&self) -> &Self::Target {
1827 match self {
1828 SignalReadGuard::Read(i) => i,
1829 SignalReadGuard::Memo(i) => i,
1830 SignalReadGuard::Owned(i) => i,
1831 }
1832 }
1833 }
1834
1835 impl<T, S> Borrow<T> for SignalReadGuard<T, S>
1836 where
1837 S: Storage<T>,
1838 {
1839 fn borrow(&self) -> &T {
1840 self.deref()
1841 }
1842 }
1843
1844 impl<T, S> PartialEq<T> for SignalReadGuard<T, S>
1845 where
1846 S: Storage<T>,
1847 T: PartialEq,
1848 {
1849 fn eq(&self, other: &T) -> bool {
1850 self.deref() == other
1851 }
1852 }
1853
1854 impl<T, S> Display for SignalReadGuard<T, S>
1855 where
1856 S: Storage<T>,
1857 T: Display,
1858 {
1859 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1860 Display::fmt(&**self, f)
1861 }
1862 }
1863}
1864
1865pub mod write {
1867 use crate::{
1868 owner::{ArenaItem, Storage, SyncStorage},
1869 signal::{ArcRwSignal, ArcWriteSignal, RwSignal, WriteSignal},
1870 traits::Set,
1871 };
1872
1873 pub trait IntoSignalSetter<T, S>: Sized {
1875 fn into_signal_setter(self) -> SignalSetter<T, S>;
1877 }
1878
1879 impl<F, T, S> IntoSignalSetter<T, S> for F
1880 where
1881 F: Fn(T) + 'static + Send + Sync,
1882 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
1883 {
1884 fn into_signal_setter(self) -> SignalSetter<T, S> {
1885 SignalSetter::map(self)
1886 }
1887 }
1888
1889 #[derive(Debug, PartialEq, Eq)]
1923 pub struct SignalSetter<T, S = SyncStorage>
1924 where
1925 T: 'static,
1926 {
1927 inner: SignalSetterTypes<T, S>,
1928 #[cfg(any(debug_assertions, leptos_debuginfo))]
1929 defined_at: &'static std::panic::Location<'static>,
1930 }
1931
1932 impl<T, S> Clone for SignalSetter<T, S> {
1933 fn clone(&self) -> Self {
1934 *self
1935 }
1936 }
1937
1938 impl<T: Default + 'static, S> Default for SignalSetter<T, S> {
1939 #[track_caller]
1940 fn default() -> Self {
1941 Self {
1942 inner: SignalSetterTypes::Default,
1943 #[cfg(any(debug_assertions, leptos_debuginfo))]
1944 defined_at: std::panic::Location::caller(),
1945 }
1946 }
1947 }
1948
1949 impl<T, S> Copy for SignalSetter<T, S> {}
1950
1951 impl<T, S> Set for SignalSetter<T, S>
1952 where
1953 T: 'static,
1954 S: Storage<ArcWriteSignal<T>> + Storage<Box<dyn Fn(T) + Send + Sync>>,
1955 {
1956 type Value = T;
1957
1958 fn set(&self, new_value: Self::Value) {
1959 match self.inner {
1960 SignalSetterTypes::Default => {}
1961 SignalSetterTypes::Write(w) => w.set(new_value),
1962 SignalSetterTypes::Mapped(s) => {
1963 s.try_with_value(|setter| setter(new_value));
1964 }
1965 }
1966 }
1967
1968 fn try_set(&self, new_value: Self::Value) -> Option<Self::Value> {
1969 match self.inner {
1970 SignalSetterTypes::Default => Some(new_value),
1971 SignalSetterTypes::Write(w) => w.try_set(new_value),
1972 SignalSetterTypes::Mapped(s) => {
1973 let mut new_value = Some(new_value);
1974
1975 let _ = s.try_with_value(|setter| {
1976 setter(new_value.take().unwrap())
1977 });
1978
1979 new_value
1980 }
1981 }
1982 }
1983 }
1984
1985 impl<T, S> SignalSetter<T, S>
1986 where
1987 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
1988 {
1989 #[track_caller]
1991 pub fn map(mapped_setter: impl Fn(T) + Send + Sync + 'static) -> Self {
1992 Self {
1993 inner: SignalSetterTypes::Mapped(ArenaItem::new_with_storage(
1994 Box::new(mapped_setter),
1995 )),
1996 #[cfg(any(debug_assertions, leptos_debuginfo))]
1997 defined_at: std::panic::Location::caller(),
1998 }
1999 }
2000 }
2001
2002 impl<T, S> From<WriteSignal<T, S>> for SignalSetter<T, S> {
2003 #[track_caller]
2004 fn from(value: WriteSignal<T, S>) -> Self {
2005 Self {
2006 inner: SignalSetterTypes::Write(value),
2007 #[cfg(any(debug_assertions, leptos_debuginfo))]
2008 defined_at: std::panic::Location::caller(),
2009 }
2010 }
2011 }
2012
2013 impl<T, S> From<RwSignal<T, S>> for SignalSetter<T, S>
2014 where
2015 T: Send + Sync + 'static,
2016 S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>>,
2017 {
2018 #[track_caller]
2019 fn from(value: RwSignal<T, S>) -> Self {
2020 Self {
2021 inner: SignalSetterTypes::Write(value.write_only()),
2022 #[cfg(any(debug_assertions, leptos_debuginfo))]
2023 defined_at: std::panic::Location::caller(),
2024 }
2025 }
2026 }
2027
2028 enum SignalSetterTypes<T, S = SyncStorage>
2029 where
2030 T: 'static,
2031 {
2032 Write(WriteSignal<T, S>),
2033 Mapped(ArenaItem<Box<dyn Fn(T) + Send + Sync>, S>),
2034 Default,
2035 }
2036
2037 impl<T, S> Clone for SignalSetterTypes<T, S> {
2038 fn clone(&self) -> Self {
2039 *self
2040 }
2041 }
2042
2043 impl<T, S> Copy for SignalSetterTypes<T, S> {}
2044
2045 impl<T, S> core::fmt::Debug for SignalSetterTypes<T, S>
2046 where
2047 T: core::fmt::Debug,
2048 S: core::fmt::Debug,
2049 {
2050 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2051 match self {
2052 Self::Write(arg0) => {
2053 f.debug_tuple("WriteSignal").field(arg0).finish()
2054 }
2055 Self::Mapped(_) => f.debug_tuple("Mapped").finish(),
2056 Self::Default => {
2057 f.debug_tuple("SignalSetter<Default>").finish()
2058 }
2059 }
2060 }
2061 }
2062
2063 impl<T, S> PartialEq for SignalSetterTypes<T, S>
2064 where
2065 T: PartialEq,
2066 {
2067 fn eq(&self, other: &Self) -> bool {
2068 match (self, other) {
2069 (Self::Write(l0), Self::Write(r0)) => l0 == r0,
2070 (Self::Mapped(l0), Self::Mapped(r0)) => std::ptr::eq(l0, r0),
2071 _ => false,
2072 }
2073 }
2074 }
2075
2076 impl<T, S> Eq for SignalSetterTypes<T, S> where T: PartialEq {}
2077}