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, S> From<ReadSignal<T, S>> for ArcSignal<T, S>
261 where
262 S: Storage<ArcReadSignal<T>> + Storage<T>,
263 {
264 #[track_caller]
265 fn from(value: ReadSignal<T, S>) -> Self {
266 Self {
267 inner: SignalTypes::ReadSignal(value.into()),
268 #[cfg(any(debug_assertions, leptos_debuginfo))]
269 defined_at: std::panic::Location::caller(),
270 }
271 }
272 }
273
274 impl<T: Send + Sync> From<ArcRwSignal<T>> for ArcSignal<T, SyncStorage> {
275 #[track_caller]
276 fn from(value: ArcRwSignal<T>) -> Self {
277 Self {
278 inner: SignalTypes::ReadSignal(value.read_only()),
279 #[cfg(any(debug_assertions, leptos_debuginfo))]
280 defined_at: std::panic::Location::caller(),
281 }
282 }
283 }
284
285 impl<T, S> From<RwSignal<T, S>> for ArcSignal<T, S>
286 where
287 S: Storage<ArcRwSignal<T>> + Storage<ArcReadSignal<T>> + Storage<T>,
288 {
289 #[track_caller]
290 fn from(value: RwSignal<T, S>) -> Self {
291 Self {
292 inner: SignalTypes::ReadSignal(value.read_only().into()),
293 #[cfg(any(debug_assertions, leptos_debuginfo))]
294 defined_at: std::panic::Location::caller(),
295 }
296 }
297 }
298
299 impl<T, S> From<ArcMemo<T, S>> for ArcSignal<T, S>
300 where
301 S: Storage<T>,
302 {
303 #[track_caller]
304 fn from(value: ArcMemo<T, S>) -> Self {
305 Self {
306 inner: SignalTypes::Memo(value),
307 #[cfg(any(debug_assertions, leptos_debuginfo))]
308 defined_at: std::panic::Location::caller(),
309 }
310 }
311 }
312
313 impl<T, S> From<Memo<T, S>> for ArcSignal<T, S>
314 where
315 S: Storage<ArcMemo<T, S>> + Storage<T>,
316 {
317 #[track_caller]
318 fn from(value: Memo<T, S>) -> Self {
319 Self {
320 inner: SignalTypes::Memo(value.into()),
321 #[cfg(any(debug_assertions, leptos_debuginfo))]
322 defined_at: std::panic::Location::caller(),
323 }
324 }
325 }
326
327 impl<T, S> DefinedAt for ArcSignal<T, S>
328 where
329 S: Storage<T>,
330 {
331 fn defined_at(&self) -> Option<&'static Location<'static>> {
332 #[cfg(any(debug_assertions, leptos_debuginfo))]
333 {
334 Some(self.defined_at)
335 }
336 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
337 {
338 None
339 }
340 }
341 }
342
343 impl<T, S> Track for ArcSignal<T, S>
344 where
345 S: Storage<T>,
346 {
347 fn track(&self) {
348 match &self.inner {
349 SignalTypes::ReadSignal(i) => {
350 i.track();
351 }
352 SignalTypes::Memo(i) => {
353 i.track();
354 }
355 SignalTypes::DerivedSignal(i) => {
356 i();
357 }
358 SignalTypes::Stored(_) => {}
360 }
361 }
362 }
363
364 impl<T, S> ReadUntracked for ArcSignal<T, S>
365 where
366 S: Storage<T>,
367 {
368 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
369
370 fn try_read_untracked(&self) -> Option<Self::Value> {
371 match &self.inner {
372 SignalTypes::ReadSignal(i) => {
373 i.try_read_untracked().map(SignalReadGuard::Read)
374 }
375 SignalTypes::Memo(i) => {
376 i.try_read_untracked().map(SignalReadGuard::Memo)
377 }
378 SignalTypes::DerivedSignal(i) => {
379 Some(SignalReadGuard::Owned(untrack(|| i())))
380 }
381 SignalTypes::Stored(i) => {
382 i.try_read_value().map(SignalReadGuard::Read)
383 }
384 }
385 .map(ReadGuard::new)
386 }
387
388 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
391 Some(
392 match &self.inner {
393 SignalTypes::ReadSignal(i) => {
394 i.try_read().map(SignalReadGuard::Read)
395 }
396 SignalTypes::Memo(i) => {
397 i.try_read().map(SignalReadGuard::Memo)
398 }
399 SignalTypes::DerivedSignal(i) => {
400 Some(SignalReadGuard::Owned(i()))
401 }
402 SignalTypes::Stored(i) => {
403 i.try_read_value().map(SignalReadGuard::Read)
404 }
405 }
406 .map(ReadGuard::new),
407 )
408 }
409 }
410
411 pub struct Signal<T, S = SyncStorage>
437 where
438 S: Storage<T>,
439 {
440 #[cfg(any(debug_assertions, leptos_debuginfo))]
441 defined_at: &'static Location<'static>,
442 inner: ArenaItem<SignalTypes<T, S>, S>,
443 }
444
445 impl<T, S> Dispose for Signal<T, S>
446 where
447 S: Storage<T>,
448 {
449 fn dispose(self) {
450 self.inner.dispose()
451 }
452 }
453
454 impl<T, S> Clone for Signal<T, S>
455 where
456 S: Storage<T>,
457 {
458 fn clone(&self) -> Self {
459 *self
460 }
461 }
462
463 impl<T, S> Copy for Signal<T, S> where S: Storage<T> {}
464
465 impl<T, S> core::fmt::Debug for Signal<T, S>
466 where
467 S: std::fmt::Debug + Storage<T>,
468 {
469 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
470 let mut s = f.debug_struct("Signal");
471 s.field("inner", &self.inner);
472 #[cfg(any(debug_assertions, leptos_debuginfo))]
473 s.field("defined_at", &self.defined_at);
474 s.finish()
475 }
476 }
477
478 impl<T, S> Eq for Signal<T, S> where S: Storage<T> {}
479
480 impl<T, S> PartialEq for Signal<T, S>
481 where
482 S: Storage<T>,
483 {
484 fn eq(&self, other: &Self) -> bool {
485 self.inner == other.inner
486 }
487 }
488
489 impl<T, S> DefinedAt for Signal<T, S>
490 where
491 S: Storage<T>,
492 {
493 fn defined_at(&self) -> Option<&'static Location<'static>> {
494 #[cfg(any(debug_assertions, leptos_debuginfo))]
495 {
496 Some(self.defined_at)
497 }
498 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
499 {
500 None
501 }
502 }
503 }
504
505 impl<T, S> Track for Signal<T, S>
506 where
507 T: 'static,
508 S: Storage<T> + Storage<SignalTypes<T, S>>,
509 {
510 fn track(&self) {
511 let inner = self
512 .inner
513 .try_with_value(Clone::clone)
516 .unwrap_or_else(unwrap_signal!(self));
517 match inner {
518 SignalTypes::ReadSignal(i) => {
519 i.track();
520 }
521 SignalTypes::Memo(i) => {
522 i.track();
523 }
524 SignalTypes::DerivedSignal(i) => {
525 i();
526 }
527 SignalTypes::Stored(_) => {}
529 }
530 }
531 }
532
533 impl<T, S> ReadUntracked for Signal<T, S>
534 where
535 T: 'static,
536 S: Storage<SignalTypes<T, S>> + Storage<T>,
537 {
538 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
539
540 fn try_read_untracked(&self) -> Option<Self::Value> {
541 self.inner
542 .try_with_value(Clone::clone)
545 .and_then(|inner| {
546 match &inner {
547 SignalTypes::ReadSignal(i) => {
548 i.try_read_untracked().map(SignalReadGuard::Read)
549 }
550 SignalTypes::Memo(i) => {
551 i.try_read_untracked().map(SignalReadGuard::Memo)
552 }
553 SignalTypes::DerivedSignal(i) => {
554 Some(SignalReadGuard::Owned(untrack(|| i())))
555 }
556 SignalTypes::Stored(i) => {
557 i.try_read_value().map(SignalReadGuard::Read)
558 }
559 }
560 .map(ReadGuard::new)
561 })
562 }
563
564 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
567 Some(
568 self.inner
569 .try_with_value(Clone::clone)
572 .and_then(|inner| {
573 match &inner {
574 SignalTypes::ReadSignal(i) => {
575 i.try_read().map(SignalReadGuard::Read)
576 }
577 SignalTypes::Memo(i) => {
578 i.try_read().map(SignalReadGuard::Memo)
579 }
580 SignalTypes::DerivedSignal(i) => {
581 Some(SignalReadGuard::Owned(i()))
582 }
583 SignalTypes::Stored(i) => {
584 i.try_read_value().map(SignalReadGuard::Read)
585 }
586 }
587 .map(ReadGuard::new)
588 }),
589 )
590 }
591 }
592
593 impl<T> Signal<T>
594 where
595 T: Send + Sync + 'static,
596 {
597 #[track_caller]
615 pub fn derive(
616 derived_signal: impl Fn() -> T + Send + Sync + 'static,
617 ) -> Self {
618 #[cfg(feature = "tracing")]
619 let span = ::tracing::Span::current();
620
621 let derived_signal = move || {
622 #[cfg(feature = "tracing")]
623 let _guard = span.enter();
624 derived_signal()
625 };
626
627 Self {
628 inner: ArenaItem::new_with_storage(SignalTypes::DerivedSignal(
629 Arc::new(derived_signal),
630 )),
631 #[cfg(any(debug_assertions, leptos_debuginfo))]
632 defined_at: std::panic::Location::caller(),
633 }
634 }
635
636 #[track_caller]
638 pub fn stored(value: T) -> Self {
639 Self {
640 inner: ArenaItem::new_with_storage(SignalTypes::Stored(
641 ArcStoredValue::new(value),
642 )),
643 #[cfg(any(debug_assertions, leptos_debuginfo))]
644 defined_at: std::panic::Location::caller(),
645 }
646 }
647 }
648
649 impl<T> Signal<T, LocalStorage>
650 where
651 T: 'static,
652 {
653 #[track_caller]
655 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
656 let derived_signal = SendWrapper::new(derived_signal);
657 #[cfg(feature = "tracing")]
658 let span = ::tracing::Span::current();
659
660 let derived_signal = move || {
661 #[cfg(feature = "tracing")]
662 let _guard = span.enter();
663 derived_signal()
664 };
665
666 Self {
667 inner: ArenaItem::new_local(SignalTypes::DerivedSignal(
668 Arc::new(derived_signal),
669 )),
670 #[cfg(any(debug_assertions, leptos_debuginfo))]
671 defined_at: std::panic::Location::caller(),
672 }
673 }
674
675 #[track_caller]
678 pub fn stored_local(value: T) -> Self {
679 Self {
680 inner: ArenaItem::new_local(SignalTypes::Stored(
681 ArcStoredValue::new(value),
682 )),
683 #[cfg(any(debug_assertions, leptos_debuginfo))]
684 defined_at: std::panic::Location::caller(),
685 }
686 }
687 }
688
689 impl<T> Default for Signal<T>
690 where
691 T: Send + Sync + Default + 'static,
692 {
693 fn default() -> Self {
694 Self::stored(Default::default())
695 }
696 }
697
698 impl<T> Default for Signal<T, LocalStorage>
699 where
700 T: Default + 'static,
701 {
702 fn default() -> Self {
703 Self::stored_local(Default::default())
704 }
705 }
706
707 impl<T: Send + Sync + 'static> From<T> for ArcSignal<T, SyncStorage> {
708 #[track_caller]
709 fn from(value: T) -> Self {
710 ArcSignal::stored(value)
711 }
712 }
713
714 impl<T> From<T> for Signal<T>
715 where
716 T: Send + Sync + 'static,
717 {
718 #[track_caller]
719 fn from(value: T) -> Self {
720 Self::stored(value)
721 }
722 }
723
724 impl<T> From<T> for Signal<T, LocalStorage>
725 where
726 T: 'static,
727 {
728 #[track_caller]
729 fn from(value: T) -> Self {
730 Self::stored_local(value)
731 }
732 }
733
734 impl<T> From<ArcSignal<T, SyncStorage>> for Signal<T>
735 where
736 T: Send + Sync + 'static,
737 {
738 #[track_caller]
739 fn from(value: ArcSignal<T, SyncStorage>) -> Self {
740 Signal {
741 #[cfg(any(debug_assertions, leptos_debuginfo))]
742 defined_at: Location::caller(),
743 inner: ArenaItem::new(value.inner),
744 }
745 }
746 }
747
748 impl<T> FromLocal<ArcSignal<T, LocalStorage>> for Signal<T, LocalStorage>
749 where
750 T: 'static,
751 {
752 #[track_caller]
753 fn from_local(value: ArcSignal<T, LocalStorage>) -> Self {
754 Signal {
755 #[cfg(any(debug_assertions, leptos_debuginfo))]
756 defined_at: Location::caller(),
757 inner: ArenaItem::new_local(value.inner),
758 }
759 }
760 }
761
762 impl<T, S> From<Signal<T, S>> for ArcSignal<T, S>
763 where
764 S: Storage<SignalTypes<T, S>> + Storage<T>,
765 {
766 #[track_caller]
767 fn from(value: Signal<T, S>) -> Self {
768 ArcSignal {
769 #[cfg(any(debug_assertions, leptos_debuginfo))]
770 defined_at: Location::caller(),
771 inner: value
772 .inner
773 .try_get_value()
774 .unwrap_or_else(unwrap_signal!(value)),
775 }
776 }
777 }
778
779 impl<T> From<ReadSignal<T>> for Signal<T>
780 where
781 T: Send + Sync + 'static,
782 {
783 #[track_caller]
784 fn from(value: ReadSignal<T>) -> Self {
785 Self {
786 inner: ArenaItem::new(SignalTypes::ReadSignal(value.into())),
787 #[cfg(any(debug_assertions, leptos_debuginfo))]
788 defined_at: std::panic::Location::caller(),
789 }
790 }
791 }
792
793 impl<T> From<ReadSignal<T, LocalStorage>> for Signal<T, LocalStorage>
794 where
795 T: 'static,
796 {
797 #[track_caller]
798 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
799 Self {
800 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
801 value.into(),
802 )),
803 #[cfg(any(debug_assertions, leptos_debuginfo))]
804 defined_at: std::panic::Location::caller(),
805 }
806 }
807 }
808
809 impl<T> From<ArcReadSignal<T>> for Signal<T>
810 where
811 T: Send + Sync + 'static,
812 {
813 #[track_caller]
814 fn from(value: ArcReadSignal<T>) -> Self {
815 Self {
816 inner: ArenaItem::new(SignalTypes::ReadSignal(value)),
817 #[cfg(any(debug_assertions, leptos_debuginfo))]
818 defined_at: std::panic::Location::caller(),
819 }
820 }
821 }
822
823 impl<T> From<ArcReadSignal<T>> for Signal<T, LocalStorage>
824 where
825 T: Send + Sync + 'static,
826 {
827 #[track_caller]
828 fn from(value: ArcReadSignal<T>) -> Self {
829 Self {
830 inner: ArenaItem::new_local(SignalTypes::ReadSignal(value)),
831 #[cfg(any(debug_assertions, leptos_debuginfo))]
832 defined_at: std::panic::Location::caller(),
833 }
834 }
835 }
836
837 impl<T> From<RwSignal<T>> for Signal<T>
838 where
839 T: Send + Sync + 'static,
840 {
841 #[track_caller]
842 fn from(value: RwSignal<T>) -> Self {
843 Self {
844 inner: ArenaItem::new(SignalTypes::ReadSignal(
845 value.read_only().into(),
846 )),
847 #[cfg(any(debug_assertions, leptos_debuginfo))]
848 defined_at: std::panic::Location::caller(),
849 }
850 }
851 }
852
853 impl<T> From<MappedSignal<T>> for Signal<T>
854 where
855 T: Clone + Send + Sync + 'static,
856 {
857 #[track_caller]
858 fn from(value: MappedSignal<T>) -> Self {
859 Self::derive(move || value.get())
860 }
861 }
862
863 impl<T> From<RwSignal<T, LocalStorage>> for Signal<T, LocalStorage>
864 where
865 T: 'static,
866 {
867 #[track_caller]
868 fn from(value: RwSignal<T, LocalStorage>) -> Self {
869 Self {
870 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
871 value.read_only().into(),
872 )),
873 #[cfg(any(debug_assertions, leptos_debuginfo))]
874 defined_at: std::panic::Location::caller(),
875 }
876 }
877 }
878
879 impl<T> From<ArcRwSignal<T>> for Signal<T>
880 where
881 T: Send + Sync + 'static,
882 {
883 #[track_caller]
884 fn from(value: ArcRwSignal<T>) -> Self {
885 Self {
886 inner: ArenaItem::new(SignalTypes::ReadSignal(
887 value.read_only(),
888 )),
889 #[cfg(any(debug_assertions, leptos_debuginfo))]
890 defined_at: std::panic::Location::caller(),
891 }
892 }
893 }
894
895 impl<T> From<ArcMappedSignal<T>> for Signal<T>
896 where
897 T: Clone + Send + Sync + 'static,
898 {
899 #[track_caller]
900 fn from(value: ArcMappedSignal<T>) -> Self {
901 MappedSignal::from(value).into()
902 }
903 }
904
905 impl<T> From<ArcRwSignal<T>> for Signal<T, LocalStorage>
906 where
907 T: Send + Sync + 'static,
908 {
909 #[track_caller]
910 fn from(value: ArcRwSignal<T>) -> Self {
911 Self {
912 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
913 value.read_only(),
914 )),
915 #[cfg(any(debug_assertions, leptos_debuginfo))]
916 defined_at: std::panic::Location::caller(),
917 }
918 }
919 }
920
921 impl<T> From<Memo<T>> for Signal<T>
922 where
923 T: Send + Sync + 'static,
924 {
925 #[track_caller]
926 fn from(value: Memo<T>) -> Self {
927 Self {
928 inner: ArenaItem::new(SignalTypes::Memo(value.into())),
929 #[cfg(any(debug_assertions, leptos_debuginfo))]
930 defined_at: std::panic::Location::caller(),
931 }
932 }
933 }
934
935 impl<T> From<Memo<T, LocalStorage>> for Signal<T, LocalStorage>
936 where
937 T: 'static,
938 {
939 #[track_caller]
940 fn from(value: Memo<T, LocalStorage>) -> Self {
941 Self {
942 inner: ArenaItem::new_local(SignalTypes::Memo(value.into())),
943 #[cfg(any(debug_assertions, leptos_debuginfo))]
944 defined_at: std::panic::Location::caller(),
945 }
946 }
947 }
948
949 impl<T> From<ArcMemo<T>> for Signal<T>
950 where
951 T: Send + Sync + 'static,
952 {
953 #[track_caller]
954 fn from(value: ArcMemo<T>) -> Self {
955 Self {
956 inner: ArenaItem::new(SignalTypes::Memo(value)),
957 #[cfg(any(debug_assertions, leptos_debuginfo))]
958 defined_at: std::panic::Location::caller(),
959 }
960 }
961 }
962
963 impl<T> From<ArcMemo<T, LocalStorage>> for Signal<T, LocalStorage>
964 where
965 T: Send + Sync + 'static,
966 {
967 #[track_caller]
968 fn from(value: ArcMemo<T, LocalStorage>) -> Self {
969 Self {
970 inner: ArenaItem::new_local(SignalTypes::Memo(value)),
971 #[cfg(any(debug_assertions, leptos_debuginfo))]
972 defined_at: std::panic::Location::caller(),
973 }
974 }
975 }
976
977 impl<T> From<T> for Signal<Option<T>>
978 where
979 T: Send + Sync + 'static,
980 {
981 #[track_caller]
982 fn from(value: T) -> Self {
983 Signal::stored(Some(value))
984 }
985 }
986
987 impl<T> From<T> for Signal<Option<T>, LocalStorage>
988 where
989 T: 'static,
990 {
991 #[track_caller]
992 fn from(value: T) -> Self {
993 Signal::stored_local(Some(value))
994 }
995 }
996
997 impl<T> From<Signal<T>> for Signal<Option<T>>
998 where
999 T: Clone + Send + Sync + 'static,
1000 {
1001 #[track_caller]
1002 fn from(value: Signal<T>) -> Self {
1003 Signal::derive(move || Some(value.get()))
1004 }
1005 }
1006
1007 impl<T> From<Signal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
1008 where
1009 T: Clone + 'static,
1010 {
1011 #[track_caller]
1012 fn from(value: Signal<T, LocalStorage>) -> Self {
1013 Signal::derive_local(move || Some(value.get()))
1014 }
1015 }
1016
1017 impl From<&str> for Signal<String> {
1018 #[track_caller]
1019 fn from(value: &str) -> Self {
1020 Signal::stored(value.to_string())
1021 }
1022 }
1023
1024 impl From<&str> for Signal<String, LocalStorage> {
1025 #[track_caller]
1026 fn from(value: &str) -> Self {
1027 Signal::stored_local(value.to_string())
1028 }
1029 }
1030
1031 impl From<&str> for Signal<Option<String>> {
1032 #[track_caller]
1033 fn from(value: &str) -> Self {
1034 Signal::stored(Some(value.to_string()))
1035 }
1036 }
1037
1038 impl From<&str> for Signal<Option<String>, LocalStorage> {
1039 #[track_caller]
1040 fn from(value: &str) -> Self {
1041 Signal::stored_local(Some(value.to_string()))
1042 }
1043 }
1044
1045 impl From<Signal<&'static str>> for Signal<String> {
1046 #[track_caller]
1047 fn from(value: Signal<&'static str>) -> Self {
1048 Signal::derive(move || value.read().to_string())
1049 }
1050 }
1051
1052 impl From<Signal<&'static str>> for Signal<String, LocalStorage> {
1053 #[track_caller]
1054 fn from(value: Signal<&'static str>) -> Self {
1055 Signal::derive_local(move || value.read().to_string())
1056 }
1057 }
1058
1059 impl From<Signal<&'static str>> for Signal<Option<String>> {
1060 #[track_caller]
1061 fn from(value: Signal<&'static str>) -> Self {
1062 Signal::derive(move || Some(value.read().to_string()))
1063 }
1064 }
1065
1066 impl From<Signal<&'static str>> for Signal<Option<String>, LocalStorage> {
1067 #[track_caller]
1068 fn from(value: Signal<&'static str>) -> Self {
1069 Signal::derive_local(move || Some(value.read().to_string()))
1070 }
1071 }
1072
1073 impl From<Signal<Option<&'static str>>> for Signal<Option<String>> {
1074 #[track_caller]
1075 fn from(value: Signal<Option<&'static str>>) -> Self {
1076 Signal::derive(move || value.read().map(str::to_string))
1077 }
1078 }
1079
1080 impl From<Signal<Option<&'static str>>>
1081 for Signal<Option<String>, LocalStorage>
1082 {
1083 #[track_caller]
1084 fn from(value: Signal<Option<&'static str>>) -> Self {
1085 Signal::derive_local(move || value.read().map(str::to_string))
1086 }
1087 }
1088
1089 #[allow(deprecated)]
1090 impl<T> From<MaybeSignal<T>> for Signal<T>
1091 where
1092 T: Send + Sync + 'static,
1093 {
1094 #[track_caller]
1095 fn from(value: MaybeSignal<T>) -> Self {
1096 match value {
1097 MaybeSignal::Static(value) => Signal::stored(value),
1098 MaybeSignal::Dynamic(signal) => signal,
1099 }
1100 }
1101 }
1102
1103 #[allow(deprecated)]
1104 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<T, LocalStorage>
1105 where
1106 T: Send + Sync + 'static,
1107 {
1108 #[track_caller]
1109 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1110 match value {
1111 MaybeSignal::Static(value) => Signal::stored_local(value),
1112 MaybeSignal::Dynamic(signal) => signal,
1113 }
1114 }
1115 }
1116
1117 #[allow(deprecated)]
1118 impl<T> From<MaybeSignal<T>> for Signal<Option<T>>
1119 where
1120 T: Clone + Send + Sync + 'static,
1121 {
1122 #[track_caller]
1123 fn from(value: MaybeSignal<T>) -> Self {
1124 match value {
1125 MaybeSignal::Static(value) => Signal::stored(Some(value)),
1126 MaybeSignal::Dynamic(signal) => {
1127 Signal::derive(move || Some(signal.get()))
1128 }
1129 }
1130 }
1131 }
1132
1133 #[allow(deprecated)]
1134 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
1135 where
1136 T: Clone + Send + Sync + 'static,
1137 {
1138 #[track_caller]
1139 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1140 match value {
1141 MaybeSignal::Static(value) => Signal::stored_local(Some(value)),
1142 MaybeSignal::Dynamic(signal) => {
1143 Signal::derive_local(move || Some(signal.get()))
1144 }
1145 }
1146 }
1147 }
1148
1149 impl<T> From<MaybeProp<T>> for Option<Signal<Option<T>>>
1150 where
1151 T: Send + Sync + 'static,
1152 {
1153 #[track_caller]
1154 fn from(value: MaybeProp<T>) -> Self {
1155 value.0
1156 }
1157 }
1158
1159 impl<T> From<MaybeProp<T, LocalStorage>>
1160 for Option<Signal<Option<T>, LocalStorage>>
1161 where
1162 T: Send + Sync + 'static,
1163 {
1164 #[track_caller]
1165 fn from(value: MaybeProp<T, LocalStorage>) -> Self {
1166 value.0
1167 }
1168 }
1169
1170 #[derive(Debug, PartialEq, Eq)]
1198 #[deprecated(
1199 since = "0.7.0-rc3",
1200 note = "`MaybeSignal<T>` is deprecated in favour of `Signal<T>` which \
1201 is `Copy`, now has a more efficient From<T> implementation \
1202 and other benefits in 0.7."
1203 )]
1204 pub enum MaybeSignal<T, S = SyncStorage>
1205 where
1206 T: 'static,
1207 S: Storage<T>,
1208 {
1209 Static(T),
1211 Dynamic(Signal<T, S>),
1213 }
1214
1215 #[allow(deprecated)]
1216 impl<T: Clone, S> Clone for MaybeSignal<T, S>
1217 where
1218 S: Storage<T>,
1219 {
1220 fn clone(&self) -> Self {
1221 match self {
1222 Self::Static(item) => Self::Static(item.clone()),
1223 Self::Dynamic(signal) => Self::Dynamic(*signal),
1224 }
1225 }
1226 }
1227
1228 #[allow(deprecated)]
1229 impl<T: Copy, S> Copy for MaybeSignal<T, S> where S: Storage<T> {}
1230
1231 #[allow(deprecated)]
1232 impl<T: Default, S> Default for MaybeSignal<T, S>
1233 where
1234 S: Storage<T>,
1235 {
1236 fn default() -> Self {
1237 Self::Static(Default::default())
1238 }
1239 }
1240
1241 #[allow(deprecated)]
1242 impl<T, S> DefinedAt for MaybeSignal<T, S>
1243 where
1244 S: Storage<T>,
1245 {
1246 fn defined_at(&self) -> Option<&'static Location<'static>> {
1247 None
1250 }
1251 }
1252
1253 #[allow(deprecated)]
1254 impl<T, S> Track for MaybeSignal<T, S>
1255 where
1256 S: Storage<T> + Storage<SignalTypes<T, S>>,
1257 {
1258 fn track(&self) {
1259 match self {
1260 Self::Static(_) => {}
1261 Self::Dynamic(signal) => signal.track(),
1262 }
1263 }
1264 }
1265
1266 #[allow(deprecated)]
1267 impl<T, S> ReadUntracked for MaybeSignal<T, S>
1268 where
1269 T: Clone,
1270 S: Storage<SignalTypes<T, S>> + Storage<T>,
1271 {
1272 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
1273
1274 fn try_read_untracked(&self) -> Option<Self::Value> {
1275 match self {
1276 Self::Static(t) => {
1277 Some(ReadGuard::new(SignalReadGuard::Owned(t.clone())))
1278 }
1279 Self::Dynamic(s) => s.try_read_untracked(),
1280 }
1281 }
1282
1283 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1284 match self {
1285 Self::Static(_) => None,
1286 Self::Dynamic(s) => s.custom_try_read(),
1287 }
1288 }
1289 }
1290
1291 #[allow(deprecated)]
1292 impl<T> MaybeSignal<T>
1293 where
1294 T: Send + Sync,
1295 {
1296 pub fn derive(
1299 derived_signal: impl Fn() -> T + Send + Sync + 'static,
1300 ) -> Self {
1301 Self::Dynamic(Signal::derive(derived_signal))
1302 }
1303 }
1304
1305 #[allow(deprecated)]
1306 impl<T> MaybeSignal<T, LocalStorage> {
1307 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
1310 Self::Dynamic(Signal::derive_local(derived_signal))
1311 }
1312 }
1313
1314 #[allow(deprecated)]
1315 impl<T> From<T> for MaybeSignal<T, SyncStorage>
1316 where
1317 SyncStorage: Storage<T>,
1318 {
1319 fn from(value: T) -> Self {
1320 Self::Static(value)
1321 }
1322 }
1323
1324 #[allow(deprecated)]
1325 impl<T> FromLocal<T> for MaybeSignal<T, LocalStorage>
1326 where
1327 LocalStorage: Storage<T>,
1328 {
1329 fn from_local(value: T) -> Self {
1330 Self::Static(value)
1331 }
1332 }
1333
1334 #[allow(deprecated)]
1335 impl<T> From<ReadSignal<T>> for MaybeSignal<T>
1336 where
1337 T: Send + Sync,
1338 {
1339 fn from(value: ReadSignal<T>) -> Self {
1340 Self::Dynamic(value.into())
1341 }
1342 }
1343
1344 #[allow(deprecated)]
1345 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1346 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1347 Self::Dynamic(value.into())
1348 }
1349 }
1350
1351 #[allow(deprecated)]
1352 impl<T> From<RwSignal<T>> for MaybeSignal<T>
1353 where
1354 T: Send + Sync,
1355 {
1356 fn from(value: RwSignal<T>) -> Self {
1357 Self::Dynamic(value.into())
1358 }
1359 }
1360
1361 #[allow(deprecated)]
1362 impl<T> From<RwSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1363 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1364 Self::Dynamic(value.into())
1365 }
1366 }
1367
1368 #[allow(deprecated)]
1369 impl<T> From<Memo<T>> for MaybeSignal<T>
1370 where
1371 T: Send + Sync,
1372 {
1373 fn from(value: Memo<T>) -> Self {
1374 Self::Dynamic(value.into())
1375 }
1376 }
1377
1378 #[allow(deprecated)]
1379 impl<T> From<Memo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1380 fn from(value: Memo<T, LocalStorage>) -> Self {
1381 Self::Dynamic(value.into())
1382 }
1383 }
1384
1385 #[allow(deprecated)]
1386 impl<T> From<ArcReadSignal<T>> for MaybeSignal<T>
1387 where
1388 T: Send + Sync,
1389 {
1390 fn from(value: ArcReadSignal<T>) -> Self {
1391 ReadSignal::from(value).into()
1392 }
1393 }
1394
1395 #[allow(deprecated)]
1396 impl<T> FromLocal<ArcReadSignal<T>> for MaybeSignal<T, LocalStorage> {
1397 fn from_local(value: ArcReadSignal<T>) -> Self {
1398 ReadSignal::from_local(value).into()
1399 }
1400 }
1401
1402 #[allow(deprecated)]
1403 impl<T> From<ArcRwSignal<T>> for MaybeSignal<T>
1404 where
1405 T: Send + Sync + 'static,
1406 {
1407 fn from(value: ArcRwSignal<T>) -> Self {
1408 RwSignal::from(value).into()
1409 }
1410 }
1411
1412 #[allow(deprecated)]
1413 impl<T> FromLocal<ArcRwSignal<T>> for MaybeSignal<T, LocalStorage>
1414 where
1415 T: 'static,
1416 {
1417 fn from_local(value: ArcRwSignal<T>) -> Self {
1418 RwSignal::from_local(value).into()
1419 }
1420 }
1421
1422 #[allow(deprecated)]
1423 impl<T> From<ArcMemo<T>> for MaybeSignal<T>
1424 where
1425 T: Send + Sync,
1426 {
1427 fn from(value: ArcMemo<T>) -> Self {
1428 Memo::from(value).into()
1429 }
1430 }
1431
1432 #[allow(deprecated)]
1433 impl<T> FromLocal<ArcMemo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1434 fn from_local(value: ArcMemo<T, LocalStorage>) -> Self {
1435 Memo::from_local(value).into()
1436 }
1437 }
1438
1439 #[allow(deprecated)]
1440 impl<T, S> From<Signal<T, S>> for MaybeSignal<T, S>
1441 where
1442 S: Storage<T>,
1443 {
1444 fn from(value: Signal<T, S>) -> Self {
1445 Self::Dynamic(value)
1446 }
1447 }
1448
1449 #[allow(deprecated)]
1450 impl<S> From<&str> for MaybeSignal<String, S>
1451 where
1452 S: Storage<String> + Storage<Arc<RwLock<String>>>,
1453 {
1454 fn from(value: &str) -> Self {
1455 Self::Static(value.to_string())
1456 }
1457 }
1458
1459 #[derive(Debug, PartialEq, Eq)]
1492 pub struct MaybeProp<T: 'static, S = SyncStorage>(
1493 pub(crate) Option<Signal<Option<T>, S>>,
1494 )
1495 where
1496 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>;
1497
1498 impl<T, S> Clone for MaybeProp<T, S>
1499 where
1500 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1501 {
1502 fn clone(&self) -> Self {
1503 *self
1504 }
1505 }
1506
1507 impl<T, S> Copy for MaybeProp<T, S> where
1508 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>
1509 {
1510 }
1511
1512 impl<T, S> Default for MaybeProp<T, S>
1513 where
1514 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1515 {
1516 fn default() -> Self {
1517 Self(None)
1518 }
1519 }
1520
1521 impl<T, S> DefinedAt for MaybeProp<T, S>
1522 where
1523 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1524 {
1525 fn defined_at(&self) -> Option<&'static Location<'static>> {
1526 None
1528 }
1529 }
1530
1531 impl<T, S> Track for MaybeProp<T, S>
1532 where
1533 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1534 {
1535 fn track(&self) {
1536 match &self.0 {
1537 None => {}
1538 Some(signal) => signal.track(),
1539 }
1540 }
1541 }
1542
1543 impl<T, S> ReadUntracked for MaybeProp<T, S>
1544 where
1545 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1546 {
1547 type Value = ReadGuard<Option<T>, SignalReadGuard<Option<T>, S>>;
1548
1549 fn try_read_untracked(&self) -> Option<Self::Value> {
1550 match &self.0 {
1551 None => Some(ReadGuard::new(SignalReadGuard::Owned(None))),
1552 Some(inner) => inner.try_read_untracked(),
1553 }
1554 }
1555
1556 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1557 match &self.0 {
1558 None => None,
1559 Some(inner) => inner.custom_try_read(),
1560 }
1561 }
1562 }
1563
1564 impl<T> MaybeProp<T>
1565 where
1566 T: Send + Sync,
1567 {
1568 pub fn derive(
1571 derived_signal: impl Fn() -> Option<T> + Send + Sync + 'static,
1572 ) -> Self {
1573 Self(Some(Signal::derive(derived_signal)))
1574 }
1575 }
1576
1577 impl<T> From<T> for MaybeProp<T>
1578 where
1579 T: Send + Sync,
1580 SyncStorage: Storage<Option<T>>,
1581 {
1582 fn from(value: T) -> Self {
1583 Self(Some(Signal::stored(Some(value))))
1584 }
1585 }
1586
1587 impl<T> From<Option<T>> for MaybeProp<T>
1588 where
1589 T: Send + Sync,
1590 SyncStorage: Storage<Option<T>>,
1591 {
1592 fn from(value: Option<T>) -> Self {
1593 Self(Some(Signal::stored(value)))
1594 }
1595 }
1596
1597 #[allow(deprecated)]
1598 impl<T> From<MaybeSignal<Option<T>>> for MaybeProp<T>
1599 where
1600 T: Send + Sync,
1601 SyncStorage: Storage<Option<T>>,
1602 {
1603 fn from(value: MaybeSignal<Option<T>>) -> Self {
1604 Self(Some(value.into()))
1605 }
1606 }
1607
1608 #[allow(deprecated)]
1609 impl<T> From<Option<MaybeSignal<Option<T>>>> for MaybeProp<T>
1610 where
1611 T: Send + Sync,
1612 SyncStorage: Storage<Option<T>>,
1613 {
1614 fn from(value: Option<MaybeSignal<Option<T>>>) -> Self {
1615 Self(value.map(Into::into))
1616 }
1617 }
1618
1619 impl<T> From<ReadSignal<Option<T>>> for MaybeProp<T>
1620 where
1621 T: Send + Sync,
1622 {
1623 fn from(value: ReadSignal<Option<T>>) -> Self {
1624 Self(Some(value.into()))
1625 }
1626 }
1627
1628 impl<T> From<RwSignal<Option<T>>> for MaybeProp<T>
1629 where
1630 T: Send + Sync,
1631 {
1632 fn from(value: RwSignal<Option<T>>) -> Self {
1633 Self(Some(value.into()))
1634 }
1635 }
1636
1637 impl<T> From<Memo<Option<T>>> for MaybeProp<T>
1638 where
1639 T: Send + Sync,
1640 {
1641 fn from(value: Memo<Option<T>>) -> Self {
1642 Self(Some(value.into()))
1643 }
1644 }
1645
1646 impl<T> From<Signal<Option<T>>> for MaybeProp<T>
1647 where
1648 T: Send + Sync,
1649 SyncStorage: Storage<Option<T>>,
1650 {
1651 fn from(value: Signal<Option<T>>) -> Self {
1652 Self(Some(value))
1653 }
1654 }
1655
1656 impl<T> From<ReadSignal<T>> for MaybeProp<T>
1657 where
1658 T: Send + Sync + Clone,
1659 {
1660 fn from(value: ReadSignal<T>) -> Self {
1661 Self(Some(Signal::derive(move || Some(value.get()))))
1662 }
1663 }
1664
1665 impl<T> From<RwSignal<T>> for MaybeProp<T>
1666 where
1667 T: Send + Sync + Clone,
1668 {
1669 fn from(value: RwSignal<T>) -> Self {
1670 Self(Some(Signal::derive(move || Some(value.get()))))
1671 }
1672 }
1673
1674 impl<T> From<Memo<T>> for MaybeProp<T>
1675 where
1676 T: Send + Sync + Clone,
1677 {
1678 fn from(value: Memo<T>) -> Self {
1679 Self(Some(Signal::derive(move || Some(value.get()))))
1680 }
1681 }
1682
1683 impl<T> From<Signal<T>> for MaybeProp<T>
1684 where
1685 T: Send + Sync + Clone,
1686 {
1687 fn from(value: Signal<T>) -> Self {
1688 Self(Some(Signal::derive(move || Some(value.get()))))
1689 }
1690 }
1691
1692 impl From<&str> for MaybeProp<String> {
1693 fn from(value: &str) -> Self {
1694 Self(Some(Signal::from(Some(value.to_string()))))
1695 }
1696 }
1697
1698 impl<T> MaybeProp<T, LocalStorage> {
1699 pub fn derive_local(
1702 derived_signal: impl Fn() -> Option<T> + 'static,
1703 ) -> Self {
1704 Self(Some(Signal::derive_local(derived_signal)))
1705 }
1706 }
1707
1708 impl<T> FromLocal<T> for MaybeProp<T, LocalStorage> {
1709 fn from_local(value: T) -> Self {
1710 Self(Some(Signal::stored_local(Some(value))))
1711 }
1712 }
1713
1714 impl<T> FromLocal<Option<T>> for MaybeProp<T, LocalStorage> {
1715 fn from_local(value: Option<T>) -> Self {
1716 Self(Some(Signal::stored_local(value)))
1717 }
1718 }
1719
1720 #[allow(deprecated)]
1721 impl<T> From<MaybeSignal<Option<T>, LocalStorage>>
1722 for MaybeProp<T, LocalStorage>
1723 where
1724 T: Send + Sync,
1725 {
1726 fn from(value: MaybeSignal<Option<T>, LocalStorage>) -> Self {
1727 Self(Some(value.into()))
1728 }
1729 }
1730
1731 #[allow(deprecated)]
1732 impl<T> From<Option<MaybeSignal<Option<T>, LocalStorage>>>
1733 for MaybeProp<T, LocalStorage>
1734 where
1735 T: Send + Sync,
1736 {
1737 fn from(value: Option<MaybeSignal<Option<T>, LocalStorage>>) -> Self {
1738 Self(value.map(Into::into))
1739 }
1740 }
1741
1742 impl<T> From<ReadSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1743 where
1744 T: Send + Sync,
1745 {
1746 fn from(value: ReadSignal<Option<T>, LocalStorage>) -> Self {
1747 Self(Some(value.into()))
1748 }
1749 }
1750
1751 impl<T> From<RwSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1752 where
1753 T: Send + Sync,
1754 {
1755 fn from(value: RwSignal<Option<T>, LocalStorage>) -> Self {
1756 Self(Some(value.into()))
1757 }
1758 }
1759
1760 impl<T> From<Memo<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1761 where
1762 T: Send + Sync,
1763 {
1764 fn from(value: Memo<Option<T>, LocalStorage>) -> Self {
1765 Self(Some(value.into()))
1766 }
1767 }
1768
1769 impl<T> From<Signal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage> {
1770 fn from(value: Signal<Option<T>, LocalStorage>) -> Self {
1771 Self(Some(value))
1772 }
1773 }
1774
1775 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1776 where
1777 T: Send + Sync + Clone,
1778 {
1779 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1780 Self(Some(Signal::derive_local(move || Some(value.get()))))
1781 }
1782 }
1783
1784 impl<T> From<RwSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1785 where
1786 T: Send + Sync + Clone,
1787 {
1788 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1789 Self(Some(Signal::derive_local(move || Some(value.get()))))
1790 }
1791 }
1792
1793 impl<T> From<Memo<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1794 where
1795 T: Send + Sync + Clone,
1796 {
1797 fn from(value: Memo<T, LocalStorage>) -> Self {
1798 Self(Some(Signal::derive_local(move || Some(value.get()))))
1799 }
1800 }
1801
1802 impl<T> From<Signal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1803 where
1804 T: Send + Sync + Clone,
1805 {
1806 fn from(value: Signal<T, LocalStorage>) -> Self {
1807 Self(Some(Signal::derive_local(move || Some(value.get()))))
1808 }
1809 }
1810
1811 impl From<&str> for MaybeProp<String, LocalStorage> {
1812 fn from(value: &str) -> Self {
1813 Self(Some(Signal::stored_local(Some(value.to_string()))))
1814 }
1815 }
1816
1817 pub enum SignalReadGuard<T: 'static, S: Storage<T>> {
1819 Read(ReadGuard<T, Plain<T>>),
1821 #[allow(clippy::type_complexity)]
1822 Memo(
1824 ReadGuard<T, Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>>,
1825 ),
1826 Owned(T),
1828 }
1829
1830 impl<T: 'static + std::fmt::Debug, S: Storage<T> + std::fmt::Debug>
1831 std::fmt::Debug for SignalReadGuard<T, S>
1832 where
1833 <S as Storage<T>>::Wrapped: std::fmt::Debug,
1834 {
1835 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1836 match self {
1837 Self::Read(arg0) => f.debug_tuple("Read").field(arg0).finish(),
1838 Self::Memo(arg0) => f.debug_tuple("Memo").field(arg0).finish(),
1839 Self::Owned(arg0) => {
1840 f.debug_tuple("Owned").field(arg0).finish()
1841 }
1842 }
1843 }
1844 }
1845
1846 impl<T, S> Clone for SignalReadGuard<T, S>
1847 where
1848 S: Storage<T>,
1849 T: Clone,
1850 Plain<T>: Clone,
1851 Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>: Clone,
1852 {
1853 fn clone(&self) -> Self {
1854 match self {
1855 SignalReadGuard::Read(i) => SignalReadGuard::Read(i.clone()),
1856 SignalReadGuard::Memo(i) => SignalReadGuard::Memo(i.clone()),
1857 SignalReadGuard::Owned(i) => SignalReadGuard::Owned(i.clone()),
1858 }
1859 }
1860 }
1861
1862 impl<T, S> Deref for SignalReadGuard<T, S>
1863 where
1864 S: Storage<T>,
1865 {
1866 type Target = T;
1867 fn deref(&self) -> &Self::Target {
1868 match self {
1869 SignalReadGuard::Read(i) => i,
1870 SignalReadGuard::Memo(i) => i,
1871 SignalReadGuard::Owned(i) => i,
1872 }
1873 }
1874 }
1875
1876 impl<T, S> Borrow<T> for SignalReadGuard<T, S>
1877 where
1878 S: Storage<T>,
1879 {
1880 fn borrow(&self) -> &T {
1881 self.deref()
1882 }
1883 }
1884
1885 impl<T, S> PartialEq<T> for SignalReadGuard<T, S>
1886 where
1887 S: Storage<T>,
1888 T: PartialEq,
1889 {
1890 fn eq(&self, other: &T) -> bool {
1891 self.deref() == other
1892 }
1893 }
1894
1895 impl<T, S> Display for SignalReadGuard<T, S>
1896 where
1897 S: Storage<T>,
1898 T: Display,
1899 {
1900 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1901 Display::fmt(&**self, f)
1902 }
1903 }
1904}
1905
1906pub mod write {
1908 use crate::{
1909 owner::{ArenaItem, Storage, SyncStorage},
1910 signal::{ArcRwSignal, ArcWriteSignal, RwSignal, WriteSignal},
1911 traits::Set,
1912 };
1913
1914 pub trait IntoSignalSetter<T, S>: Sized {
1916 fn into_signal_setter(self) -> SignalSetter<T, S>;
1918 }
1919
1920 impl<F, T, S> IntoSignalSetter<T, S> for F
1921 where
1922 F: Fn(T) + 'static + Send + Sync,
1923 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
1924 {
1925 fn into_signal_setter(self) -> SignalSetter<T, S> {
1926 SignalSetter::map(self)
1927 }
1928 }
1929
1930 #[derive(Debug, PartialEq, Eq)]
1964 pub struct SignalSetter<T, S = SyncStorage>
1965 where
1966 T: 'static,
1967 {
1968 inner: SignalSetterTypes<T, S>,
1969 #[cfg(any(debug_assertions, leptos_debuginfo))]
1970 defined_at: &'static std::panic::Location<'static>,
1971 }
1972
1973 impl<T, S> Clone for SignalSetter<T, S> {
1974 fn clone(&self) -> Self {
1975 *self
1976 }
1977 }
1978
1979 impl<T: Default + 'static, S> Default for SignalSetter<T, S> {
1980 #[track_caller]
1981 fn default() -> Self {
1982 Self {
1983 inner: SignalSetterTypes::Default,
1984 #[cfg(any(debug_assertions, leptos_debuginfo))]
1985 defined_at: std::panic::Location::caller(),
1986 }
1987 }
1988 }
1989
1990 impl<T, S> Copy for SignalSetter<T, S> {}
1991
1992 impl<T, S> Set for SignalSetter<T, S>
1993 where
1994 T: 'static,
1995 S: Storage<ArcWriteSignal<T>> + Storage<Box<dyn Fn(T) + Send + Sync>>,
1996 {
1997 type Value = T;
1998
1999 fn set(&self, new_value: Self::Value) {
2000 match self.inner {
2001 SignalSetterTypes::Default => {}
2002 SignalSetterTypes::Write(w) => w.set(new_value),
2003 SignalSetterTypes::Mapped(s) => {
2004 s.try_with_value(|setter| setter(new_value));
2005 }
2006 }
2007 }
2008
2009 fn try_set(&self, new_value: Self::Value) -> Option<Self::Value> {
2010 match self.inner {
2011 SignalSetterTypes::Default => Some(new_value),
2012 SignalSetterTypes::Write(w) => w.try_set(new_value),
2013 SignalSetterTypes::Mapped(s) => {
2014 let mut new_value = Some(new_value);
2015
2016 let _ = s.try_with_value(|setter| {
2017 setter(new_value.take().unwrap())
2018 });
2019
2020 new_value
2021 }
2022 }
2023 }
2024 }
2025
2026 impl<T, S> SignalSetter<T, S>
2027 where
2028 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
2029 {
2030 #[track_caller]
2032 pub fn map(mapped_setter: impl Fn(T) + Send + Sync + 'static) -> Self {
2033 Self {
2034 inner: SignalSetterTypes::Mapped(ArenaItem::new_with_storage(
2035 Box::new(mapped_setter),
2036 )),
2037 #[cfg(any(debug_assertions, leptos_debuginfo))]
2038 defined_at: std::panic::Location::caller(),
2039 }
2040 }
2041 }
2042
2043 impl<T, S> From<WriteSignal<T, S>> for SignalSetter<T, S> {
2044 #[track_caller]
2045 fn from(value: WriteSignal<T, S>) -> Self {
2046 Self {
2047 inner: SignalSetterTypes::Write(value),
2048 #[cfg(any(debug_assertions, leptos_debuginfo))]
2049 defined_at: std::panic::Location::caller(),
2050 }
2051 }
2052 }
2053
2054 impl<T, S> From<RwSignal<T, S>> for SignalSetter<T, S>
2055 where
2056 T: Send + Sync + 'static,
2057 S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>>,
2058 {
2059 #[track_caller]
2060 fn from(value: RwSignal<T, S>) -> Self {
2061 Self {
2062 inner: SignalSetterTypes::Write(value.write_only()),
2063 #[cfg(any(debug_assertions, leptos_debuginfo))]
2064 defined_at: std::panic::Location::caller(),
2065 }
2066 }
2067 }
2068
2069 enum SignalSetterTypes<T, S = SyncStorage>
2070 where
2071 T: 'static,
2072 {
2073 Write(WriteSignal<T, S>),
2074 Mapped(ArenaItem<Box<dyn Fn(T) + Send + Sync>, S>),
2075 Default,
2076 }
2077
2078 impl<T, S> Clone for SignalSetterTypes<T, S> {
2079 fn clone(&self) -> Self {
2080 *self
2081 }
2082 }
2083
2084 impl<T, S> Copy for SignalSetterTypes<T, S> {}
2085
2086 impl<T, S> core::fmt::Debug for SignalSetterTypes<T, S>
2087 where
2088 T: core::fmt::Debug,
2089 S: core::fmt::Debug,
2090 {
2091 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2092 match self {
2093 Self::Write(arg0) => {
2094 f.debug_tuple("WriteSignal").field(arg0).finish()
2095 }
2096 Self::Mapped(_) => f.debug_tuple("Mapped").finish(),
2097 Self::Default => {
2098 f.debug_tuple("SignalSetter<Default>").finish()
2099 }
2100 }
2101 }
2102 }
2103
2104 impl<T, S> PartialEq for SignalSetterTypes<T, S>
2105 where
2106 T: PartialEq,
2107 {
2108 fn eq(&self, other: &Self) -> bool {
2109 match (self, other) {
2110 (Self::Write(l0), Self::Write(r0)) => l0 == r0,
2111 (Self::Mapped(l0), Self::Mapped(r0)) => std::ptr::eq(l0, r0),
2112 _ => false,
2113 }
2114 }
2115 }
2116
2117 impl<T, S> Eq for SignalSetterTypes<T, S> where T: PartialEq {}
2118}