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 T: Clone,
1546 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1547 {
1548 type Value = ReadGuard<Option<T>, SignalReadGuard<Option<T>, S>>;
1549
1550 fn try_read_untracked(&self) -> Option<Self::Value> {
1551 match &self.0 {
1552 None => Some(ReadGuard::new(SignalReadGuard::Owned(None))),
1553 Some(inner) => inner.try_read_untracked(),
1554 }
1555 }
1556
1557 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1558 match &self.0 {
1559 None => None,
1560 Some(inner) => inner.custom_try_read(),
1561 }
1562 }
1563 }
1564
1565 impl<T> MaybeProp<T>
1566 where
1567 T: Send + Sync,
1568 {
1569 pub fn derive(
1572 derived_signal: impl Fn() -> Option<T> + Send + Sync + 'static,
1573 ) -> Self {
1574 Self(Some(Signal::derive(derived_signal)))
1575 }
1576 }
1577
1578 impl<T> From<T> for MaybeProp<T>
1579 where
1580 T: Send + Sync,
1581 SyncStorage: Storage<Option<T>>,
1582 {
1583 fn from(value: T) -> Self {
1584 Self(Some(Signal::stored(Some(value))))
1585 }
1586 }
1587
1588 impl<T> From<Option<T>> for MaybeProp<T>
1589 where
1590 T: Send + Sync,
1591 SyncStorage: Storage<Option<T>>,
1592 {
1593 fn from(value: Option<T>) -> Self {
1594 Self(Some(Signal::stored(value)))
1595 }
1596 }
1597
1598 #[allow(deprecated)]
1599 impl<T> From<MaybeSignal<Option<T>>> for MaybeProp<T>
1600 where
1601 T: Send + Sync,
1602 SyncStorage: Storage<Option<T>>,
1603 {
1604 fn from(value: MaybeSignal<Option<T>>) -> Self {
1605 Self(Some(value.into()))
1606 }
1607 }
1608
1609 #[allow(deprecated)]
1610 impl<T> From<Option<MaybeSignal<Option<T>>>> for MaybeProp<T>
1611 where
1612 T: Send + Sync,
1613 SyncStorage: Storage<Option<T>>,
1614 {
1615 fn from(value: Option<MaybeSignal<Option<T>>>) -> Self {
1616 Self(value.map(Into::into))
1617 }
1618 }
1619
1620 impl<T> From<ReadSignal<Option<T>>> for MaybeProp<T>
1621 where
1622 T: Send + Sync,
1623 {
1624 fn from(value: ReadSignal<Option<T>>) -> Self {
1625 Self(Some(value.into()))
1626 }
1627 }
1628
1629 impl<T> From<RwSignal<Option<T>>> for MaybeProp<T>
1630 where
1631 T: Send + Sync,
1632 {
1633 fn from(value: RwSignal<Option<T>>) -> Self {
1634 Self(Some(value.into()))
1635 }
1636 }
1637
1638 impl<T> From<Memo<Option<T>>> for MaybeProp<T>
1639 where
1640 T: Send + Sync,
1641 {
1642 fn from(value: Memo<Option<T>>) -> Self {
1643 Self(Some(value.into()))
1644 }
1645 }
1646
1647 impl<T> From<Signal<Option<T>>> for MaybeProp<T>
1648 where
1649 T: Send + Sync,
1650 SyncStorage: Storage<Option<T>>,
1651 {
1652 fn from(value: Signal<Option<T>>) -> Self {
1653 Self(Some(value))
1654 }
1655 }
1656
1657 impl<T> From<ReadSignal<T>> for MaybeProp<T>
1658 where
1659 T: Send + Sync + Clone,
1660 {
1661 fn from(value: ReadSignal<T>) -> Self {
1662 Self(Some(Signal::derive(move || Some(value.get()))))
1663 }
1664 }
1665
1666 impl<T> From<RwSignal<T>> for MaybeProp<T>
1667 where
1668 T: Send + Sync + Clone,
1669 {
1670 fn from(value: RwSignal<T>) -> Self {
1671 Self(Some(Signal::derive(move || Some(value.get()))))
1672 }
1673 }
1674
1675 impl<T> From<Memo<T>> for MaybeProp<T>
1676 where
1677 T: Send + Sync + Clone,
1678 {
1679 fn from(value: Memo<T>) -> Self {
1680 Self(Some(Signal::derive(move || Some(value.get()))))
1681 }
1682 }
1683
1684 impl<T> From<Signal<T>> for MaybeProp<T>
1685 where
1686 T: Send + Sync + Clone,
1687 {
1688 fn from(value: Signal<T>) -> Self {
1689 Self(Some(Signal::derive(move || Some(value.get()))))
1690 }
1691 }
1692
1693 impl From<&str> for MaybeProp<String> {
1694 fn from(value: &str) -> Self {
1695 Self(Some(Signal::from(Some(value.to_string()))))
1696 }
1697 }
1698
1699 impl<T> MaybeProp<T, LocalStorage> {
1700 pub fn derive_local(
1703 derived_signal: impl Fn() -> Option<T> + 'static,
1704 ) -> Self {
1705 Self(Some(Signal::derive_local(derived_signal)))
1706 }
1707 }
1708
1709 impl<T> FromLocal<T> for MaybeProp<T, LocalStorage> {
1710 fn from_local(value: T) -> Self {
1711 Self(Some(Signal::stored_local(Some(value))))
1712 }
1713 }
1714
1715 impl<T> FromLocal<Option<T>> for MaybeProp<T, LocalStorage> {
1716 fn from_local(value: Option<T>) -> Self {
1717 Self(Some(Signal::stored_local(value)))
1718 }
1719 }
1720
1721 #[allow(deprecated)]
1722 impl<T> From<MaybeSignal<Option<T>, LocalStorage>>
1723 for MaybeProp<T, LocalStorage>
1724 where
1725 T: Send + Sync,
1726 {
1727 fn from(value: MaybeSignal<Option<T>, LocalStorage>) -> Self {
1728 Self(Some(value.into()))
1729 }
1730 }
1731
1732 #[allow(deprecated)]
1733 impl<T> From<Option<MaybeSignal<Option<T>, LocalStorage>>>
1734 for MaybeProp<T, LocalStorage>
1735 where
1736 T: Send + Sync,
1737 {
1738 fn from(value: Option<MaybeSignal<Option<T>, LocalStorage>>) -> Self {
1739 Self(value.map(Into::into))
1740 }
1741 }
1742
1743 impl<T> From<ReadSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1744 where
1745 T: Send + Sync,
1746 {
1747 fn from(value: ReadSignal<Option<T>, LocalStorage>) -> Self {
1748 Self(Some(value.into()))
1749 }
1750 }
1751
1752 impl<T> From<RwSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1753 where
1754 T: Send + Sync,
1755 {
1756 fn from(value: RwSignal<Option<T>, LocalStorage>) -> Self {
1757 Self(Some(value.into()))
1758 }
1759 }
1760
1761 impl<T> From<Memo<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1762 where
1763 T: Send + Sync,
1764 {
1765 fn from(value: Memo<Option<T>, LocalStorage>) -> Self {
1766 Self(Some(value.into()))
1767 }
1768 }
1769
1770 impl<T> From<Signal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage> {
1771 fn from(value: Signal<Option<T>, LocalStorage>) -> Self {
1772 Self(Some(value))
1773 }
1774 }
1775
1776 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1777 where
1778 T: Send + Sync + Clone,
1779 {
1780 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1781 Self(Some(Signal::derive_local(move || Some(value.get()))))
1782 }
1783 }
1784
1785 impl<T> From<RwSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1786 where
1787 T: Send + Sync + Clone,
1788 {
1789 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1790 Self(Some(Signal::derive_local(move || Some(value.get()))))
1791 }
1792 }
1793
1794 impl<T> From<Memo<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1795 where
1796 T: Send + Sync + Clone,
1797 {
1798 fn from(value: Memo<T, LocalStorage>) -> Self {
1799 Self(Some(Signal::derive_local(move || Some(value.get()))))
1800 }
1801 }
1802
1803 impl<T> From<Signal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1804 where
1805 T: Send + Sync + Clone,
1806 {
1807 fn from(value: Signal<T, LocalStorage>) -> Self {
1808 Self(Some(Signal::derive_local(move || Some(value.get()))))
1809 }
1810 }
1811
1812 impl From<&str> for MaybeProp<String, LocalStorage> {
1813 fn from(value: &str) -> Self {
1814 Self(Some(Signal::stored_local(Some(value.to_string()))))
1815 }
1816 }
1817
1818 pub enum SignalReadGuard<T: 'static, S: Storage<T>> {
1820 Read(ReadGuard<T, Plain<T>>),
1822 #[allow(clippy::type_complexity)]
1823 Memo(
1825 ReadGuard<T, Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>>,
1826 ),
1827 Owned(T),
1829 }
1830
1831 impl<T: 'static + std::fmt::Debug, S: Storage<T> + std::fmt::Debug>
1832 std::fmt::Debug for SignalReadGuard<T, S>
1833 where
1834 <S as Storage<T>>::Wrapped: std::fmt::Debug,
1835 {
1836 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1837 match self {
1838 Self::Read(arg0) => f.debug_tuple("Read").field(arg0).finish(),
1839 Self::Memo(arg0) => f.debug_tuple("Memo").field(arg0).finish(),
1840 Self::Owned(arg0) => {
1841 f.debug_tuple("Owned").field(arg0).finish()
1842 }
1843 }
1844 }
1845 }
1846
1847 impl<T, S> Clone for SignalReadGuard<T, S>
1848 where
1849 S: Storage<T>,
1850 T: Clone,
1851 Plain<T>: Clone,
1852 Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>: Clone,
1853 {
1854 fn clone(&self) -> Self {
1855 match self {
1856 SignalReadGuard::Read(i) => SignalReadGuard::Read(i.clone()),
1857 SignalReadGuard::Memo(i) => SignalReadGuard::Memo(i.clone()),
1858 SignalReadGuard::Owned(i) => SignalReadGuard::Owned(i.clone()),
1859 }
1860 }
1861 }
1862
1863 impl<T, S> Deref for SignalReadGuard<T, S>
1864 where
1865 S: Storage<T>,
1866 {
1867 type Target = T;
1868 fn deref(&self) -> &Self::Target {
1869 match self {
1870 SignalReadGuard::Read(i) => i,
1871 SignalReadGuard::Memo(i) => i,
1872 SignalReadGuard::Owned(i) => i,
1873 }
1874 }
1875 }
1876
1877 impl<T, S> Borrow<T> for SignalReadGuard<T, S>
1878 where
1879 S: Storage<T>,
1880 {
1881 fn borrow(&self) -> &T {
1882 self.deref()
1883 }
1884 }
1885
1886 impl<T, S> PartialEq<T> for SignalReadGuard<T, S>
1887 where
1888 S: Storage<T>,
1889 T: PartialEq,
1890 {
1891 fn eq(&self, other: &T) -> bool {
1892 self.deref() == other
1893 }
1894 }
1895
1896 impl<T, S> Display for SignalReadGuard<T, S>
1897 where
1898 S: Storage<T>,
1899 T: Display,
1900 {
1901 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1902 Display::fmt(&**self, f)
1903 }
1904 }
1905}
1906
1907pub mod write {
1909 use crate::{
1910 owner::{ArenaItem, Storage, SyncStorage},
1911 signal::{ArcRwSignal, ArcWriteSignal, RwSignal, WriteSignal},
1912 traits::Set,
1913 };
1914
1915 pub trait IntoSignalSetter<T, S>: Sized {
1917 fn into_signal_setter(self) -> SignalSetter<T, S>;
1919 }
1920
1921 impl<F, T, S> IntoSignalSetter<T, S> for F
1922 where
1923 F: Fn(T) + 'static + Send + Sync,
1924 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
1925 {
1926 fn into_signal_setter(self) -> SignalSetter<T, S> {
1927 SignalSetter::map(self)
1928 }
1929 }
1930
1931 #[derive(Debug, PartialEq, Eq)]
1965 pub struct SignalSetter<T, S = SyncStorage>
1966 where
1967 T: 'static,
1968 {
1969 inner: SignalSetterTypes<T, S>,
1970 #[cfg(any(debug_assertions, leptos_debuginfo))]
1971 defined_at: &'static std::panic::Location<'static>,
1972 }
1973
1974 impl<T, S> Clone for SignalSetter<T, S> {
1975 fn clone(&self) -> Self {
1976 *self
1977 }
1978 }
1979
1980 impl<T: Default + 'static, S> Default for SignalSetter<T, S> {
1981 #[track_caller]
1982 fn default() -> Self {
1983 Self {
1984 inner: SignalSetterTypes::Default,
1985 #[cfg(any(debug_assertions, leptos_debuginfo))]
1986 defined_at: std::panic::Location::caller(),
1987 }
1988 }
1989 }
1990
1991 impl<T, S> Copy for SignalSetter<T, S> {}
1992
1993 impl<T, S> Set for SignalSetter<T, S>
1994 where
1995 T: 'static,
1996 S: Storage<ArcWriteSignal<T>> + Storage<Box<dyn Fn(T) + Send + Sync>>,
1997 {
1998 type Value = T;
1999
2000 fn set(&self, new_value: Self::Value) {
2001 match self.inner {
2002 SignalSetterTypes::Default => {}
2003 SignalSetterTypes::Write(w) => w.set(new_value),
2004 SignalSetterTypes::Mapped(s) => {
2005 s.try_with_value(|setter| setter(new_value));
2006 }
2007 }
2008 }
2009
2010 fn try_set(&self, new_value: Self::Value) -> Option<Self::Value> {
2011 match self.inner {
2012 SignalSetterTypes::Default => Some(new_value),
2013 SignalSetterTypes::Write(w) => w.try_set(new_value),
2014 SignalSetterTypes::Mapped(s) => {
2015 let mut new_value = Some(new_value);
2016
2017 let _ = s.try_with_value(|setter| {
2018 setter(new_value.take().unwrap())
2019 });
2020
2021 new_value
2022 }
2023 }
2024 }
2025 }
2026
2027 impl<T, S> SignalSetter<T, S>
2028 where
2029 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
2030 {
2031 #[track_caller]
2033 pub fn map(mapped_setter: impl Fn(T) + Send + Sync + 'static) -> Self {
2034 Self {
2035 inner: SignalSetterTypes::Mapped(ArenaItem::new_with_storage(
2036 Box::new(mapped_setter),
2037 )),
2038 #[cfg(any(debug_assertions, leptos_debuginfo))]
2039 defined_at: std::panic::Location::caller(),
2040 }
2041 }
2042 }
2043
2044 impl<T, S> From<WriteSignal<T, S>> for SignalSetter<T, S> {
2045 #[track_caller]
2046 fn from(value: WriteSignal<T, S>) -> Self {
2047 Self {
2048 inner: SignalSetterTypes::Write(value),
2049 #[cfg(any(debug_assertions, leptos_debuginfo))]
2050 defined_at: std::panic::Location::caller(),
2051 }
2052 }
2053 }
2054
2055 impl<T, S> From<RwSignal<T, S>> for SignalSetter<T, S>
2056 where
2057 T: Send + Sync + 'static,
2058 S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>>,
2059 {
2060 #[track_caller]
2061 fn from(value: RwSignal<T, S>) -> Self {
2062 Self {
2063 inner: SignalSetterTypes::Write(value.write_only()),
2064 #[cfg(any(debug_assertions, leptos_debuginfo))]
2065 defined_at: std::panic::Location::caller(),
2066 }
2067 }
2068 }
2069
2070 enum SignalSetterTypes<T, S = SyncStorage>
2071 where
2072 T: 'static,
2073 {
2074 Write(WriteSignal<T, S>),
2075 Mapped(ArenaItem<Box<dyn Fn(T) + Send + Sync>, S>),
2076 Default,
2077 }
2078
2079 impl<T, S> Clone for SignalSetterTypes<T, S> {
2080 fn clone(&self) -> Self {
2081 *self
2082 }
2083 }
2084
2085 impl<T, S> Copy for SignalSetterTypes<T, S> {}
2086
2087 impl<T, S> core::fmt::Debug for SignalSetterTypes<T, S>
2088 where
2089 T: core::fmt::Debug,
2090 S: core::fmt::Debug,
2091 {
2092 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2093 match self {
2094 Self::Write(arg0) => {
2095 f.debug_tuple("WriteSignal").field(arg0).finish()
2096 }
2097 Self::Mapped(_) => f.debug_tuple("Mapped").finish(),
2098 Self::Default => {
2099 f.debug_tuple("SignalSetter<Default>").finish()
2100 }
2101 }
2102 }
2103 }
2104
2105 impl<T, S> PartialEq for SignalSetterTypes<T, S>
2106 where
2107 T: PartialEq,
2108 {
2109 fn eq(&self, other: &Self) -> bool {
2110 match (self, other) {
2111 (Self::Write(l0), Self::Write(r0)) => l0 == r0,
2112 (Self::Mapped(l0), Self::Mapped(r0)) => std::ptr::eq(l0, r0),
2113 _ => false,
2114 }
2115 }
2116 }
2117
2118 impl<T, S> Eq for SignalSetterTypes<T, S> where T: PartialEq {}
2119}