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<S> From<&'static str> for ArcSignal<String, S>
328 where
329 S: Storage<&'static str> + Storage<String>,
330 {
331 #[track_caller]
332 fn from(value: &'static str) -> Self {
333 Self {
334 inner: SignalTypes::Stored(ArcStoredValue::new(
335 value.to_string(),
336 )),
337 #[cfg(any(debug_assertions, leptos_debuginfo))]
338 defined_at: std::panic::Location::caller(),
339 }
340 }
341 }
342
343 impl<T, S> DefinedAt for ArcSignal<T, S>
344 where
345 S: Storage<T>,
346 {
347 fn defined_at(&self) -> Option<&'static Location<'static>> {
348 #[cfg(any(debug_assertions, leptos_debuginfo))]
349 {
350 Some(self.defined_at)
351 }
352 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
353 {
354 None
355 }
356 }
357 }
358
359 impl<T, S> Track for ArcSignal<T, S>
360 where
361 S: Storage<T>,
362 {
363 fn track(&self) {
364 match &self.inner {
365 SignalTypes::ReadSignal(i) => {
366 i.track();
367 }
368 SignalTypes::Memo(i) => {
369 i.track();
370 }
371 SignalTypes::DerivedSignal(i) => {
372 i();
373 }
374 SignalTypes::Stored(_) => {}
376 }
377 }
378 }
379
380 impl<T, S> ReadUntracked for ArcSignal<T, S>
381 where
382 S: Storage<T>,
383 {
384 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
385
386 fn try_read_untracked(&self) -> Option<Self::Value> {
387 match &self.inner {
388 SignalTypes::ReadSignal(i) => {
389 i.try_read_untracked().map(SignalReadGuard::Read)
390 }
391 SignalTypes::Memo(i) => {
392 i.try_read_untracked().map(SignalReadGuard::Memo)
393 }
394 SignalTypes::DerivedSignal(i) => {
395 Some(SignalReadGuard::Owned(untrack(|| i())))
396 }
397 SignalTypes::Stored(i) => {
398 i.try_read_value().map(SignalReadGuard::Read)
399 }
400 }
401 .map(ReadGuard::new)
402 }
403
404 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
407 Some(
408 match &self.inner {
409 SignalTypes::ReadSignal(i) => {
410 i.try_read().map(SignalReadGuard::Read)
411 }
412 SignalTypes::Memo(i) => {
413 i.try_read().map(SignalReadGuard::Memo)
414 }
415 SignalTypes::DerivedSignal(i) => {
416 Some(SignalReadGuard::Owned(i()))
417 }
418 SignalTypes::Stored(i) => {
419 i.try_read_value().map(SignalReadGuard::Read)
420 }
421 }
422 .map(ReadGuard::new),
423 )
424 }
425 }
426
427 pub struct Signal<T, S = SyncStorage>
453 where
454 S: Storage<T>,
455 {
456 #[cfg(any(debug_assertions, leptos_debuginfo))]
457 defined_at: &'static Location<'static>,
458 inner: ArenaItem<SignalTypes<T, S>, S>,
459 }
460
461 impl<T, S> Dispose for Signal<T, S>
462 where
463 S: Storage<T>,
464 {
465 fn dispose(self) {
466 self.inner.dispose()
467 }
468 }
469
470 impl<T, S> Clone for Signal<T, S>
471 where
472 S: Storage<T>,
473 {
474 fn clone(&self) -> Self {
475 *self
476 }
477 }
478
479 impl<T, S> Copy for Signal<T, S> where S: Storage<T> {}
480
481 impl<T, S> core::fmt::Debug for Signal<T, S>
482 where
483 S: std::fmt::Debug + Storage<T>,
484 {
485 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
486 let mut s = f.debug_struct("Signal");
487 s.field("inner", &self.inner);
488 #[cfg(any(debug_assertions, leptos_debuginfo))]
489 s.field("defined_at", &self.defined_at);
490 s.finish()
491 }
492 }
493
494 impl<T, S> Eq for Signal<T, S> where S: Storage<T> {}
495
496 impl<T, S> PartialEq for Signal<T, S>
497 where
498 S: Storage<T>,
499 {
500 fn eq(&self, other: &Self) -> bool {
501 self.inner == other.inner
502 }
503 }
504
505 impl<T, S> DefinedAt for Signal<T, S>
506 where
507 S: Storage<T>,
508 {
509 fn defined_at(&self) -> Option<&'static Location<'static>> {
510 #[cfg(any(debug_assertions, leptos_debuginfo))]
511 {
512 Some(self.defined_at)
513 }
514 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
515 {
516 None
517 }
518 }
519 }
520
521 impl<T, S> Track for Signal<T, S>
522 where
523 T: 'static,
524 S: Storage<T> + Storage<SignalTypes<T, S>>,
525 {
526 fn track(&self) {
527 let inner = self
528 .inner
529 .try_with_value(Clone::clone)
532 .unwrap_or_else(unwrap_signal!(self));
533 match inner {
534 SignalTypes::ReadSignal(i) => {
535 i.track();
536 }
537 SignalTypes::Memo(i) => {
538 i.track();
539 }
540 SignalTypes::DerivedSignal(i) => {
541 i();
542 }
543 SignalTypes::Stored(_) => {}
545 }
546 }
547 }
548
549 impl<T, S> ReadUntracked for Signal<T, S>
550 where
551 T: 'static,
552 S: Storage<SignalTypes<T, S>> + Storage<T>,
553 {
554 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
555
556 fn try_read_untracked(&self) -> Option<Self::Value> {
557 self.inner
558 .try_with_value(Clone::clone)
561 .and_then(|inner| {
562 match &inner {
563 SignalTypes::ReadSignal(i) => {
564 i.try_read_untracked().map(SignalReadGuard::Read)
565 }
566 SignalTypes::Memo(i) => {
567 i.try_read_untracked().map(SignalReadGuard::Memo)
568 }
569 SignalTypes::DerivedSignal(i) => {
570 Some(SignalReadGuard::Owned(untrack(|| i())))
571 }
572 SignalTypes::Stored(i) => {
573 i.try_read_value().map(SignalReadGuard::Read)
574 }
575 }
576 .map(ReadGuard::new)
577 })
578 }
579
580 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
583 Some(
584 self.inner
585 .try_with_value(Clone::clone)
588 .and_then(|inner| {
589 match &inner {
590 SignalTypes::ReadSignal(i) => {
591 i.try_read().map(SignalReadGuard::Read)
592 }
593 SignalTypes::Memo(i) => {
594 i.try_read().map(SignalReadGuard::Memo)
595 }
596 SignalTypes::DerivedSignal(i) => {
597 Some(SignalReadGuard::Owned(i()))
598 }
599 SignalTypes::Stored(i) => {
600 i.try_read_value().map(SignalReadGuard::Read)
601 }
602 }
603 .map(ReadGuard::new)
604 }),
605 )
606 }
607 }
608
609 impl<T> Signal<T>
610 where
611 T: Send + Sync + 'static,
612 {
613 #[track_caller]
631 pub fn derive(
632 derived_signal: impl Fn() -> T + Send + Sync + 'static,
633 ) -> Self {
634 #[cfg(feature = "tracing")]
635 let span = ::tracing::Span::current();
636
637 let derived_signal = move || {
638 #[cfg(feature = "tracing")]
639 let _guard = span.enter();
640 derived_signal()
641 };
642
643 Self {
644 inner: ArenaItem::new_with_storage(SignalTypes::DerivedSignal(
645 Arc::new(derived_signal),
646 )),
647 #[cfg(any(debug_assertions, leptos_debuginfo))]
648 defined_at: std::panic::Location::caller(),
649 }
650 }
651
652 #[track_caller]
654 pub fn stored(value: T) -> Self {
655 Self {
656 inner: ArenaItem::new_with_storage(SignalTypes::Stored(
657 ArcStoredValue::new(value),
658 )),
659 #[cfg(any(debug_assertions, leptos_debuginfo))]
660 defined_at: std::panic::Location::caller(),
661 }
662 }
663 }
664
665 impl<T> Signal<T, LocalStorage>
666 where
667 T: 'static,
668 {
669 #[track_caller]
671 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
672 let derived_signal = SendWrapper::new(derived_signal);
673 #[cfg(feature = "tracing")]
674 let span = ::tracing::Span::current();
675
676 let derived_signal = move || {
677 #[cfg(feature = "tracing")]
678 let _guard = span.enter();
679 derived_signal()
680 };
681
682 Self {
683 inner: ArenaItem::new_local(SignalTypes::DerivedSignal(
684 Arc::new(derived_signal),
685 )),
686 #[cfg(any(debug_assertions, leptos_debuginfo))]
687 defined_at: std::panic::Location::caller(),
688 }
689 }
690
691 #[track_caller]
694 pub fn stored_local(value: T) -> Self {
695 Self {
696 inner: ArenaItem::new_local(SignalTypes::Stored(
697 ArcStoredValue::new(value),
698 )),
699 #[cfg(any(debug_assertions, leptos_debuginfo))]
700 defined_at: std::panic::Location::caller(),
701 }
702 }
703 }
704
705 impl<T> Default for Signal<T>
706 where
707 T: Send + Sync + Default + 'static,
708 {
709 fn default() -> Self {
710 Self::stored(Default::default())
711 }
712 }
713
714 impl<T> Default for Signal<T, LocalStorage>
715 where
716 T: Default + 'static,
717 {
718 fn default() -> Self {
719 Self::stored_local(Default::default())
720 }
721 }
722
723 impl<T: Send + Sync + 'static> From<T> for ArcSignal<T, SyncStorage> {
724 #[track_caller]
725 fn from(value: T) -> Self {
726 ArcSignal::stored(value)
727 }
728 }
729
730 impl<T> From<T> for Signal<T>
731 where
732 T: Send + Sync + 'static,
733 {
734 #[track_caller]
735 fn from(value: T) -> Self {
736 Self::stored(value)
737 }
738 }
739
740 impl<T> From<T> for Signal<T, LocalStorage>
741 where
742 T: 'static,
743 {
744 #[track_caller]
745 fn from(value: T) -> Self {
746 Self::stored_local(value)
747 }
748 }
749
750 impl<T> From<ArcSignal<T, SyncStorage>> for Signal<T>
751 where
752 T: Send + Sync + 'static,
753 {
754 #[track_caller]
755 fn from(value: ArcSignal<T, SyncStorage>) -> Self {
756 Signal {
757 #[cfg(any(debug_assertions, leptos_debuginfo))]
758 defined_at: Location::caller(),
759 inner: ArenaItem::new(value.inner),
760 }
761 }
762 }
763
764 impl<T> FromLocal<ArcSignal<T, LocalStorage>> for Signal<T, LocalStorage>
765 where
766 T: 'static,
767 {
768 #[track_caller]
769 fn from_local(value: ArcSignal<T, LocalStorage>) -> Self {
770 Signal {
771 #[cfg(any(debug_assertions, leptos_debuginfo))]
772 defined_at: Location::caller(),
773 inner: ArenaItem::new_local(value.inner),
774 }
775 }
776 }
777
778 impl<T, S> From<Signal<T, S>> for ArcSignal<T, S>
779 where
780 S: Storage<SignalTypes<T, S>> + Storage<T>,
781 {
782 #[track_caller]
783 fn from(value: Signal<T, S>) -> Self {
784 ArcSignal {
785 #[cfg(any(debug_assertions, leptos_debuginfo))]
786 defined_at: Location::caller(),
787 inner: value
788 .inner
789 .try_get_value()
790 .unwrap_or_else(unwrap_signal!(value)),
791 }
792 }
793 }
794
795 impl<T> From<ReadSignal<T>> for Signal<T>
796 where
797 T: Send + Sync + 'static,
798 {
799 #[track_caller]
800 fn from(value: ReadSignal<T>) -> Self {
801 Self {
802 inner: ArenaItem::new(SignalTypes::ReadSignal(value.into())),
803 #[cfg(any(debug_assertions, leptos_debuginfo))]
804 defined_at: std::panic::Location::caller(),
805 }
806 }
807 }
808
809 impl<T> From<ReadSignal<T, LocalStorage>> for Signal<T, LocalStorage>
810 where
811 T: 'static,
812 {
813 #[track_caller]
814 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
815 Self {
816 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
817 value.into(),
818 )),
819 #[cfg(any(debug_assertions, leptos_debuginfo))]
820 defined_at: std::panic::Location::caller(),
821 }
822 }
823 }
824
825 impl<T> From<ArcReadSignal<T>> for Signal<T>
826 where
827 T: Send + Sync + 'static,
828 {
829 #[track_caller]
830 fn from(value: ArcReadSignal<T>) -> Self {
831 Self {
832 inner: ArenaItem::new(SignalTypes::ReadSignal(value)),
833 #[cfg(any(debug_assertions, leptos_debuginfo))]
834 defined_at: std::panic::Location::caller(),
835 }
836 }
837 }
838
839 impl<T> From<ArcReadSignal<T>> for Signal<T, LocalStorage>
840 where
841 T: Send + Sync + 'static,
842 {
843 #[track_caller]
844 fn from(value: ArcReadSignal<T>) -> Self {
845 Self {
846 inner: ArenaItem::new_local(SignalTypes::ReadSignal(value)),
847 #[cfg(any(debug_assertions, leptos_debuginfo))]
848 defined_at: std::panic::Location::caller(),
849 }
850 }
851 }
852
853 impl<T> From<RwSignal<T>> for Signal<T>
854 where
855 T: Send + Sync + 'static,
856 {
857 #[track_caller]
858 fn from(value: RwSignal<T>) -> Self {
859 Self {
860 inner: ArenaItem::new(SignalTypes::ReadSignal(
861 value.read_only().into(),
862 )),
863 #[cfg(any(debug_assertions, leptos_debuginfo))]
864 defined_at: std::panic::Location::caller(),
865 }
866 }
867 }
868
869 impl<T> From<MappedSignal<T>> for Signal<T>
870 where
871 T: Clone + Send + Sync + 'static,
872 {
873 #[track_caller]
874 fn from(value: MappedSignal<T>) -> Self {
875 Self::derive(move || value.get())
876 }
877 }
878
879 impl<T> From<RwSignal<T, LocalStorage>> for Signal<T, LocalStorage>
880 where
881 T: 'static,
882 {
883 #[track_caller]
884 fn from(value: RwSignal<T, LocalStorage>) -> Self {
885 Self {
886 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
887 value.read_only().into(),
888 )),
889 #[cfg(any(debug_assertions, leptos_debuginfo))]
890 defined_at: std::panic::Location::caller(),
891 }
892 }
893 }
894
895 impl<T> From<ArcRwSignal<T>> for Signal<T>
896 where
897 T: Send + Sync + 'static,
898 {
899 #[track_caller]
900 fn from(value: ArcRwSignal<T>) -> Self {
901 Self {
902 inner: ArenaItem::new(SignalTypes::ReadSignal(
903 value.read_only(),
904 )),
905 #[cfg(any(debug_assertions, leptos_debuginfo))]
906 defined_at: std::panic::Location::caller(),
907 }
908 }
909 }
910
911 impl<T> From<ArcMappedSignal<T>> for Signal<T>
912 where
913 T: Clone + Send + Sync + 'static,
914 {
915 #[track_caller]
916 fn from(value: ArcMappedSignal<T>) -> Self {
917 MappedSignal::from(value).into()
918 }
919 }
920
921 impl<T> From<ArcRwSignal<T>> for Signal<T, LocalStorage>
922 where
923 T: Send + Sync + 'static,
924 {
925 #[track_caller]
926 fn from(value: ArcRwSignal<T>) -> Self {
927 Self {
928 inner: ArenaItem::new_local(SignalTypes::ReadSignal(
929 value.read_only(),
930 )),
931 #[cfg(any(debug_assertions, leptos_debuginfo))]
932 defined_at: std::panic::Location::caller(),
933 }
934 }
935 }
936
937 impl<T> From<Memo<T>> for Signal<T>
938 where
939 T: Send + Sync + 'static,
940 {
941 #[track_caller]
942 fn from(value: Memo<T>) -> Self {
943 Self {
944 inner: ArenaItem::new(SignalTypes::Memo(value.into())),
945 #[cfg(any(debug_assertions, leptos_debuginfo))]
946 defined_at: std::panic::Location::caller(),
947 }
948 }
949 }
950
951 impl<T> From<Memo<T, LocalStorage>> for Signal<T, LocalStorage>
952 where
953 T: 'static,
954 {
955 #[track_caller]
956 fn from(value: Memo<T, LocalStorage>) -> Self {
957 Self {
958 inner: ArenaItem::new_local(SignalTypes::Memo(value.into())),
959 #[cfg(any(debug_assertions, leptos_debuginfo))]
960 defined_at: std::panic::Location::caller(),
961 }
962 }
963 }
964
965 impl<T> From<ArcMemo<T>> for Signal<T>
966 where
967 T: Send + Sync + 'static,
968 {
969 #[track_caller]
970 fn from(value: ArcMemo<T>) -> Self {
971 Self {
972 inner: ArenaItem::new(SignalTypes::Memo(value)),
973 #[cfg(any(debug_assertions, leptos_debuginfo))]
974 defined_at: std::panic::Location::caller(),
975 }
976 }
977 }
978
979 impl<T> From<ArcMemo<T, LocalStorage>> for Signal<T, LocalStorage>
980 where
981 T: Send + Sync + 'static,
982 {
983 #[track_caller]
984 fn from(value: ArcMemo<T, LocalStorage>) -> Self {
985 Self {
986 inner: ArenaItem::new_local(SignalTypes::Memo(value)),
987 #[cfg(any(debug_assertions, leptos_debuginfo))]
988 defined_at: std::panic::Location::caller(),
989 }
990 }
991 }
992
993 impl<T> From<T> for Signal<Option<T>>
994 where
995 T: Send + Sync + 'static,
996 {
997 #[track_caller]
998 fn from(value: T) -> Self {
999 Signal::stored(Some(value))
1000 }
1001 }
1002
1003 impl<T> From<T> for Signal<Option<T>, LocalStorage>
1004 where
1005 T: 'static,
1006 {
1007 #[track_caller]
1008 fn from(value: T) -> Self {
1009 Signal::stored_local(Some(value))
1010 }
1011 }
1012
1013 impl<T> From<Signal<T>> for Signal<Option<T>>
1014 where
1015 T: Clone + Send + Sync + 'static,
1016 {
1017 #[track_caller]
1018 fn from(value: Signal<T>) -> Self {
1019 Signal::derive(move || Some(value.get()))
1020 }
1021 }
1022
1023 impl<T> From<Signal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
1024 where
1025 T: Clone + 'static,
1026 {
1027 #[track_caller]
1028 fn from(value: Signal<T, LocalStorage>) -> Self {
1029 Signal::derive_local(move || Some(value.get()))
1030 }
1031 }
1032
1033 impl From<&str> for Signal<String> {
1034 #[track_caller]
1035 fn from(value: &str) -> Self {
1036 Signal::stored(value.to_string())
1037 }
1038 }
1039
1040 impl From<&str> for Signal<String, LocalStorage> {
1041 #[track_caller]
1042 fn from(value: &str) -> Self {
1043 Signal::stored_local(value.to_string())
1044 }
1045 }
1046
1047 impl From<&str> for Signal<Option<String>> {
1048 #[track_caller]
1049 fn from(value: &str) -> Self {
1050 Signal::stored(Some(value.to_string()))
1051 }
1052 }
1053
1054 impl From<&str> for Signal<Option<String>, LocalStorage> {
1055 #[track_caller]
1056 fn from(value: &str) -> Self {
1057 Signal::stored_local(Some(value.to_string()))
1058 }
1059 }
1060
1061 impl From<Signal<&'static str>> for Signal<String> {
1062 #[track_caller]
1063 fn from(value: Signal<&'static str>) -> Self {
1064 Signal::derive(move || value.read().to_string())
1065 }
1066 }
1067
1068 impl From<Signal<&'static str, LocalStorage>> for Signal<String, LocalStorage> {
1069 #[track_caller]
1070 fn from(value: Signal<&'static str, LocalStorage>) -> Self {
1071 Signal::derive_local(move || value.read().to_string())
1072 }
1073 }
1074
1075 impl From<Signal<&'static str>> for Signal<String, LocalStorage> {
1076 #[track_caller]
1077 fn from(value: Signal<&'static str>) -> Self {
1078 Signal::derive_local(move || value.read().to_string())
1079 }
1080 }
1081
1082 impl From<Signal<&'static str>> for Signal<Option<String>> {
1083 #[track_caller]
1084 fn from(value: Signal<&'static str>) -> Self {
1085 Signal::derive(move || Some(value.read().to_string()))
1086 }
1087 }
1088
1089 impl From<Signal<&'static str>> for Signal<Option<String>, LocalStorage> {
1090 #[track_caller]
1091 fn from(value: Signal<&'static str>) -> Self {
1092 Signal::derive_local(move || Some(value.read().to_string()))
1093 }
1094 }
1095
1096 impl From<Signal<Option<&'static str>>> for Signal<Option<String>> {
1097 #[track_caller]
1098 fn from(value: Signal<Option<&'static str>>) -> Self {
1099 Signal::derive(move || value.read().map(str::to_string))
1100 }
1101 }
1102
1103 impl From<Signal<Option<&'static str>, LocalStorage>>
1104 for Signal<Option<String>, LocalStorage>
1105 {
1106 #[track_caller]
1107 fn from(value: Signal<Option<&'static str>, LocalStorage>) -> Self {
1108 Signal::derive_local(move || value.read().map(str::to_string))
1109 }
1110 }
1111
1112 impl From<Signal<Option<&'static str>>>
1113 for Signal<Option<String>, LocalStorage>
1114 {
1115 #[track_caller]
1116 fn from(value: Signal<Option<&'static str>>) -> Self {
1117 Signal::derive_local(move || value.read().map(str::to_string))
1118 }
1119 }
1120
1121 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1122 #[doc(hidden)]
1123 pub struct __IntoReactiveValueMarkerSignalFromReactiveClosure;
1124 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1125 #[doc(hidden)]
1126 pub struct __IntoReactiveValueMarkerSignalStrOutputToString;
1127 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1128 #[doc(hidden)]
1129 pub struct __IntoReactiveValueMarkerOptionalSignalFromReactiveClosureAlways;
1130
1131 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1132 impl<T, F>
1133 crate::IntoReactiveValue<
1134 Signal<T, SyncStorage>,
1135 __IntoReactiveValueMarkerSignalFromReactiveClosure,
1136 > for F
1137 where
1138 T: Send + Sync + 'static,
1139 F: Fn() -> T + Send + Sync + 'static,
1140 {
1141 fn into_reactive_value(self) -> Signal<T, SyncStorage> {
1142 Signal::derive(self)
1143 }
1144 }
1145
1146 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1147 impl<T, F>
1148 crate::IntoReactiveValue<
1149 ArcSignal<T, SyncStorage>,
1150 __IntoReactiveValueMarkerSignalFromReactiveClosure,
1151 > for F
1152 where
1153 T: Send + Sync + 'static,
1154 F: Fn() -> T + Send + Sync + 'static,
1155 {
1156 fn into_reactive_value(self) -> ArcSignal<T, SyncStorage> {
1157 ArcSignal::derive(self)
1158 }
1159 }
1160
1161 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1162 impl<T, F>
1163 crate::IntoReactiveValue<
1164 Signal<T, LocalStorage>,
1165 __IntoReactiveValueMarkerSignalFromReactiveClosure,
1166 > for F
1167 where
1168 T: 'static,
1169 F: Fn() -> T + 'static,
1170 {
1171 fn into_reactive_value(self) -> Signal<T, LocalStorage> {
1172 Signal::derive_local(self)
1173 }
1174 }
1175
1176 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1177 impl<T, F>
1178 crate::IntoReactiveValue<
1179 ArcSignal<T, LocalStorage>,
1180 __IntoReactiveValueMarkerSignalFromReactiveClosure,
1181 > for F
1182 where
1183 T: 'static,
1184 F: Fn() -> T + 'static,
1185 {
1186 fn into_reactive_value(self) -> ArcSignal<T, LocalStorage> {
1187 ArcSignal::derive_local(self)
1188 }
1189 }
1190
1191 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1192 impl<F>
1193 crate::IntoReactiveValue<
1194 Signal<String, SyncStorage>,
1195 __IntoReactiveValueMarkerSignalStrOutputToString,
1196 > for F
1197 where
1198 F: Fn() -> &'static str + Send + Sync + 'static,
1199 {
1200 fn into_reactive_value(self) -> Signal<String, SyncStorage> {
1201 Signal::derive(move || self().to_string())
1202 }
1203 }
1204
1205 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1206 impl<F>
1207 crate::IntoReactiveValue<
1208 ArcSignal<String, SyncStorage>,
1209 __IntoReactiveValueMarkerSignalStrOutputToString,
1210 > for F
1211 where
1212 F: Fn() -> &'static str + Send + Sync + 'static,
1213 {
1214 fn into_reactive_value(self) -> ArcSignal<String, SyncStorage> {
1215 ArcSignal::derive(move || self().to_string())
1216 }
1217 }
1218
1219 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1220 impl<F>
1221 crate::IntoReactiveValue<
1222 Signal<String, LocalStorage>,
1223 __IntoReactiveValueMarkerSignalStrOutputToString,
1224 > for F
1225 where
1226 F: Fn() -> &'static str + 'static,
1227 {
1228 fn into_reactive_value(self) -> Signal<String, LocalStorage> {
1229 Signal::derive_local(move || self().to_string())
1230 }
1231 }
1232
1233 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1234 impl<F>
1235 crate::IntoReactiveValue<
1236 ArcSignal<String, LocalStorage>,
1237 __IntoReactiveValueMarkerSignalStrOutputToString,
1238 > for F
1239 where
1240 F: Fn() -> &'static str + 'static,
1241 {
1242 fn into_reactive_value(self) -> ArcSignal<String, LocalStorage> {
1243 ArcSignal::derive_local(move || self().to_string())
1244 }
1245 }
1246
1247 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1248 impl<T, F>
1249 crate::IntoReactiveValue<
1250 Signal<Option<T>, SyncStorage>,
1251 __IntoReactiveValueMarkerOptionalSignalFromReactiveClosureAlways,
1252 > for F
1253 where
1254 T: Send + Sync + 'static,
1255 F: Fn() -> T + Send + Sync + 'static,
1256 {
1257 fn into_reactive_value(self) -> Signal<Option<T>, SyncStorage> {
1258 Signal::derive(move || Some(self()))
1259 }
1260 }
1261
1262 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1263 impl<T, F>
1264 crate::IntoReactiveValue<
1265 ArcSignal<Option<T>, SyncStorage>,
1266 __IntoReactiveValueMarkerOptionalSignalFromReactiveClosureAlways,
1267 > for F
1268 where
1269 T: Send + Sync + 'static,
1270 F: Fn() -> T + Send + Sync + 'static,
1271 {
1272 fn into_reactive_value(self) -> ArcSignal<Option<T>, SyncStorage> {
1273 ArcSignal::derive(move || Some(self()))
1274 }
1275 }
1276
1277 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1278 impl<T, F>
1279 crate::IntoReactiveValue<
1280 Signal<Option<T>, LocalStorage>,
1281 __IntoReactiveValueMarkerOptionalSignalFromReactiveClosureAlways,
1282 > for F
1283 where
1284 T: 'static,
1285 F: Fn() -> T + 'static,
1286 {
1287 fn into_reactive_value(self) -> Signal<Option<T>, LocalStorage> {
1288 Signal::derive_local(move || Some(self()))
1289 }
1290 }
1291
1292 #[cfg(not(all(feature = "nightly", rustc_nightly)))]
1293 impl<T, F>
1294 crate::IntoReactiveValue<
1295 ArcSignal<Option<T>, LocalStorage>,
1296 __IntoReactiveValueMarkerOptionalSignalFromReactiveClosureAlways,
1297 > for F
1298 where
1299 T: 'static,
1300 F: Fn() -> T + 'static,
1301 {
1302 fn into_reactive_value(self) -> ArcSignal<Option<T>, LocalStorage> {
1303 ArcSignal::derive_local(move || Some(self()))
1304 }
1305 }
1306
1307 #[allow(deprecated)]
1308 impl<T> From<MaybeSignal<T>> for Signal<T>
1309 where
1310 T: Send + Sync + 'static,
1311 {
1312 #[track_caller]
1313 fn from(value: MaybeSignal<T>) -> Self {
1314 match value {
1315 MaybeSignal::Static(value) => Signal::stored(value),
1316 MaybeSignal::Dynamic(signal) => signal,
1317 }
1318 }
1319 }
1320
1321 #[allow(deprecated)]
1322 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<T, LocalStorage>
1323 where
1324 T: Send + Sync + 'static,
1325 {
1326 #[track_caller]
1327 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1328 match value {
1329 MaybeSignal::Static(value) => Signal::stored_local(value),
1330 MaybeSignal::Dynamic(signal) => signal,
1331 }
1332 }
1333 }
1334
1335 #[allow(deprecated)]
1336 impl<T> From<MaybeSignal<T>> for Signal<Option<T>>
1337 where
1338 T: Clone + Send + Sync + 'static,
1339 {
1340 #[track_caller]
1341 fn from(value: MaybeSignal<T>) -> Self {
1342 match value {
1343 MaybeSignal::Static(value) => Signal::stored(Some(value)),
1344 MaybeSignal::Dynamic(signal) => {
1345 Signal::derive(move || Some(signal.get()))
1346 }
1347 }
1348 }
1349 }
1350
1351 #[allow(deprecated)]
1352 impl<T> From<MaybeSignal<T, LocalStorage>> for Signal<Option<T>, LocalStorage>
1353 where
1354 T: Clone + Send + Sync + 'static,
1355 {
1356 #[track_caller]
1357 fn from(value: MaybeSignal<T, LocalStorage>) -> Self {
1358 match value {
1359 MaybeSignal::Static(value) => Signal::stored_local(Some(value)),
1360 MaybeSignal::Dynamic(signal) => {
1361 Signal::derive_local(move || Some(signal.get()))
1362 }
1363 }
1364 }
1365 }
1366
1367 impl<T> From<MaybeProp<T>> for Option<Signal<Option<T>>>
1368 where
1369 T: Send + Sync + 'static,
1370 {
1371 #[track_caller]
1372 fn from(value: MaybeProp<T>) -> Self {
1373 value.0
1374 }
1375 }
1376
1377 impl<T> From<MaybeProp<T, LocalStorage>>
1378 for Option<Signal<Option<T>, LocalStorage>>
1379 where
1380 T: Send + Sync + 'static,
1381 {
1382 #[track_caller]
1383 fn from(value: MaybeProp<T, LocalStorage>) -> Self {
1384 value.0
1385 }
1386 }
1387
1388 #[derive(Debug, PartialEq, Eq)]
1416 #[deprecated(
1417 since = "0.7.0-rc3",
1418 note = "`MaybeSignal<T>` is deprecated in favour of `Signal<T>` which \
1419 is `Copy`, now has a more efficient From<T> implementation \
1420 and other benefits in 0.7."
1421 )]
1422 pub enum MaybeSignal<T, S = SyncStorage>
1423 where
1424 T: 'static,
1425 S: Storage<T>,
1426 {
1427 Static(T),
1429 Dynamic(Signal<T, S>),
1431 }
1432
1433 #[allow(deprecated)]
1434 impl<T: Clone, S> Clone for MaybeSignal<T, S>
1435 where
1436 S: Storage<T>,
1437 {
1438 fn clone(&self) -> Self {
1439 match self {
1440 Self::Static(item) => Self::Static(item.clone()),
1441 Self::Dynamic(signal) => Self::Dynamic(*signal),
1442 }
1443 }
1444 }
1445
1446 #[allow(deprecated)]
1447 impl<T: Copy, S> Copy for MaybeSignal<T, S> where S: Storage<T> {}
1448
1449 #[allow(deprecated)]
1450 impl<T: Default, S> Default for MaybeSignal<T, S>
1451 where
1452 S: Storage<T>,
1453 {
1454 fn default() -> Self {
1455 Self::Static(Default::default())
1456 }
1457 }
1458
1459 #[allow(deprecated)]
1460 impl<T, S> DefinedAt for MaybeSignal<T, S>
1461 where
1462 S: Storage<T>,
1463 {
1464 fn defined_at(&self) -> Option<&'static Location<'static>> {
1465 None
1468 }
1469 }
1470
1471 #[allow(deprecated)]
1472 impl<T, S> Track for MaybeSignal<T, S>
1473 where
1474 S: Storage<T> + Storage<SignalTypes<T, S>>,
1475 {
1476 fn track(&self) {
1477 match self {
1478 Self::Static(_) => {}
1479 Self::Dynamic(signal) => signal.track(),
1480 }
1481 }
1482 }
1483
1484 #[allow(deprecated)]
1485 impl<T, S> ReadUntracked for MaybeSignal<T, S>
1486 where
1487 T: Clone,
1488 S: Storage<SignalTypes<T, S>> + Storage<T>,
1489 {
1490 type Value = ReadGuard<T, SignalReadGuard<T, S>>;
1491
1492 fn try_read_untracked(&self) -> Option<Self::Value> {
1493 match self {
1494 Self::Static(t) => {
1495 Some(ReadGuard::new(SignalReadGuard::Owned(t.clone())))
1496 }
1497 Self::Dynamic(s) => s.try_read_untracked(),
1498 }
1499 }
1500
1501 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1502 match self {
1503 Self::Static(_) => None,
1504 Self::Dynamic(s) => s.custom_try_read(),
1505 }
1506 }
1507 }
1508
1509 #[allow(deprecated)]
1510 impl<T> MaybeSignal<T>
1511 where
1512 T: Send + Sync,
1513 {
1514 pub fn derive(
1517 derived_signal: impl Fn() -> T + Send + Sync + 'static,
1518 ) -> Self {
1519 Self::Dynamic(Signal::derive(derived_signal))
1520 }
1521 }
1522
1523 #[allow(deprecated)]
1524 impl<T> MaybeSignal<T, LocalStorage> {
1525 pub fn derive_local(derived_signal: impl Fn() -> T + 'static) -> Self {
1528 Self::Dynamic(Signal::derive_local(derived_signal))
1529 }
1530 }
1531
1532 #[allow(deprecated)]
1533 impl<T> From<T> for MaybeSignal<T, SyncStorage>
1534 where
1535 SyncStorage: Storage<T>,
1536 {
1537 fn from(value: T) -> Self {
1538 Self::Static(value)
1539 }
1540 }
1541
1542 #[allow(deprecated)]
1543 impl<T> FromLocal<T> for MaybeSignal<T, LocalStorage>
1544 where
1545 LocalStorage: Storage<T>,
1546 {
1547 fn from_local(value: T) -> Self {
1548 Self::Static(value)
1549 }
1550 }
1551
1552 #[allow(deprecated)]
1553 impl<T> From<ReadSignal<T>> for MaybeSignal<T>
1554 where
1555 T: Send + Sync,
1556 {
1557 fn from(value: ReadSignal<T>) -> Self {
1558 Self::Dynamic(value.into())
1559 }
1560 }
1561
1562 #[allow(deprecated)]
1563 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1564 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1565 Self::Dynamic(value.into())
1566 }
1567 }
1568
1569 #[allow(deprecated)]
1570 impl<T> From<RwSignal<T>> for MaybeSignal<T>
1571 where
1572 T: Send + Sync,
1573 {
1574 fn from(value: RwSignal<T>) -> Self {
1575 Self::Dynamic(value.into())
1576 }
1577 }
1578
1579 #[allow(deprecated)]
1580 impl<T> From<RwSignal<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1581 fn from(value: RwSignal<T, LocalStorage>) -> Self {
1582 Self::Dynamic(value.into())
1583 }
1584 }
1585
1586 #[allow(deprecated)]
1587 impl<T> From<Memo<T>> for MaybeSignal<T>
1588 where
1589 T: Send + Sync,
1590 {
1591 fn from(value: Memo<T>) -> Self {
1592 Self::Dynamic(value.into())
1593 }
1594 }
1595
1596 #[allow(deprecated)]
1597 impl<T> From<Memo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1598 fn from(value: Memo<T, LocalStorage>) -> Self {
1599 Self::Dynamic(value.into())
1600 }
1601 }
1602
1603 #[allow(deprecated)]
1604 impl<T> From<ArcReadSignal<T>> for MaybeSignal<T>
1605 where
1606 T: Send + Sync,
1607 {
1608 fn from(value: ArcReadSignal<T>) -> Self {
1609 ReadSignal::from(value).into()
1610 }
1611 }
1612
1613 #[allow(deprecated)]
1614 impl<T> FromLocal<ArcReadSignal<T>> for MaybeSignal<T, LocalStorage> {
1615 fn from_local(value: ArcReadSignal<T>) -> Self {
1616 ReadSignal::from_local(value).into()
1617 }
1618 }
1619
1620 #[allow(deprecated)]
1621 impl<T> From<ArcRwSignal<T>> for MaybeSignal<T>
1622 where
1623 T: Send + Sync + 'static,
1624 {
1625 fn from(value: ArcRwSignal<T>) -> Self {
1626 RwSignal::from(value).into()
1627 }
1628 }
1629
1630 #[allow(deprecated)]
1631 impl<T> FromLocal<ArcRwSignal<T>> for MaybeSignal<T, LocalStorage>
1632 where
1633 T: 'static,
1634 {
1635 fn from_local(value: ArcRwSignal<T>) -> Self {
1636 RwSignal::from_local(value).into()
1637 }
1638 }
1639
1640 #[allow(deprecated)]
1641 impl<T> From<ArcMemo<T>> for MaybeSignal<T>
1642 where
1643 T: Send + Sync,
1644 {
1645 fn from(value: ArcMemo<T>) -> Self {
1646 Memo::from(value).into()
1647 }
1648 }
1649
1650 #[allow(deprecated)]
1651 impl<T> FromLocal<ArcMemo<T, LocalStorage>> for MaybeSignal<T, LocalStorage> {
1652 fn from_local(value: ArcMemo<T, LocalStorage>) -> Self {
1653 Memo::from_local(value).into()
1654 }
1655 }
1656
1657 #[allow(deprecated)]
1658 impl<T, S> From<Signal<T, S>> for MaybeSignal<T, S>
1659 where
1660 S: Storage<T>,
1661 {
1662 fn from(value: Signal<T, S>) -> Self {
1663 Self::Dynamic(value)
1664 }
1665 }
1666
1667 #[allow(deprecated)]
1668 impl<S> From<&str> for MaybeSignal<String, S>
1669 where
1670 S: Storage<String> + Storage<Arc<RwLock<String>>>,
1671 {
1672 fn from(value: &str) -> Self {
1673 Self::Static(value.to_string())
1674 }
1675 }
1676
1677 #[derive(Debug, PartialEq, Eq)]
1710 pub struct MaybeProp<T: 'static, S = SyncStorage>(
1711 pub(crate) Option<Signal<Option<T>, S>>,
1712 )
1713 where
1714 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>;
1715
1716 impl<T, S> Clone for MaybeProp<T, S>
1717 where
1718 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1719 {
1720 fn clone(&self) -> Self {
1721 *self
1722 }
1723 }
1724
1725 impl<T, S> Copy for MaybeProp<T, S> where
1726 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>
1727 {
1728 }
1729
1730 impl<T, S> Default for MaybeProp<T, S>
1731 where
1732 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1733 {
1734 fn default() -> Self {
1735 Self(None)
1736 }
1737 }
1738
1739 impl<T, S> DefinedAt for MaybeProp<T, S>
1740 where
1741 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1742 {
1743 fn defined_at(&self) -> Option<&'static Location<'static>> {
1744 None
1746 }
1747 }
1748
1749 impl<T, S> Track for MaybeProp<T, S>
1750 where
1751 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1752 {
1753 fn track(&self) {
1754 match &self.0 {
1755 None => {}
1756 Some(signal) => signal.track(),
1757 }
1758 }
1759 }
1760
1761 impl<T, S> ReadUntracked for MaybeProp<T, S>
1762 where
1763 S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
1764 {
1765 type Value = ReadGuard<Option<T>, SignalReadGuard<Option<T>, S>>;
1766
1767 fn try_read_untracked(&self) -> Option<Self::Value> {
1768 match &self.0 {
1769 None => Some(ReadGuard::new(SignalReadGuard::Owned(None))),
1770 Some(inner) => inner.try_read_untracked(),
1771 }
1772 }
1773
1774 fn custom_try_read(&self) -> Option<Option<Self::Value>> {
1775 match &self.0 {
1776 None => None,
1777 Some(inner) => inner.custom_try_read(),
1778 }
1779 }
1780 }
1781
1782 impl<T> MaybeProp<T>
1783 where
1784 T: Send + Sync,
1785 {
1786 pub fn derive(
1789 derived_signal: impl Fn() -> Option<T> + Send + Sync + 'static,
1790 ) -> Self {
1791 Self(Some(Signal::derive(derived_signal)))
1792 }
1793 }
1794
1795 impl<T> From<T> for MaybeProp<T>
1796 where
1797 T: Send + Sync,
1798 SyncStorage: Storage<Option<T>>,
1799 {
1800 fn from(value: T) -> Self {
1801 Self(Some(Signal::stored(Some(value))))
1802 }
1803 }
1804
1805 impl<T> From<Option<T>> for MaybeProp<T>
1806 where
1807 T: Send + Sync,
1808 SyncStorage: Storage<Option<T>>,
1809 {
1810 fn from(value: Option<T>) -> Self {
1811 Self(Some(Signal::stored(value)))
1812 }
1813 }
1814
1815 #[allow(deprecated)]
1816 impl<T> From<MaybeSignal<Option<T>>> for MaybeProp<T>
1817 where
1818 T: Send + Sync,
1819 SyncStorage: Storage<Option<T>>,
1820 {
1821 fn from(value: MaybeSignal<Option<T>>) -> Self {
1822 Self(Some(value.into()))
1823 }
1824 }
1825
1826 #[allow(deprecated)]
1827 impl<T> From<Option<MaybeSignal<Option<T>>>> for MaybeProp<T>
1828 where
1829 T: Send + Sync,
1830 SyncStorage: Storage<Option<T>>,
1831 {
1832 fn from(value: Option<MaybeSignal<Option<T>>>) -> Self {
1833 Self(value.map(Into::into))
1834 }
1835 }
1836
1837 impl<T> From<ReadSignal<Option<T>>> for MaybeProp<T>
1838 where
1839 T: Send + Sync,
1840 {
1841 fn from(value: ReadSignal<Option<T>>) -> Self {
1842 Self(Some(value.into()))
1843 }
1844 }
1845
1846 impl<T> From<RwSignal<Option<T>>> for MaybeProp<T>
1847 where
1848 T: Send + Sync,
1849 {
1850 fn from(value: RwSignal<Option<T>>) -> Self {
1851 Self(Some(value.into()))
1852 }
1853 }
1854
1855 impl<T> From<Memo<Option<T>>> for MaybeProp<T>
1856 where
1857 T: Send + Sync,
1858 {
1859 fn from(value: Memo<Option<T>>) -> Self {
1860 Self(Some(value.into()))
1861 }
1862 }
1863
1864 impl<T> From<Signal<Option<T>>> for MaybeProp<T>
1865 where
1866 T: Send + Sync,
1867 SyncStorage: Storage<Option<T>>,
1868 {
1869 fn from(value: Signal<Option<T>>) -> Self {
1870 Self(Some(value))
1871 }
1872 }
1873
1874 impl<T> From<ReadSignal<T>> for MaybeProp<T>
1875 where
1876 T: Send + Sync + Clone,
1877 {
1878 fn from(value: ReadSignal<T>) -> Self {
1879 Self(Some(Signal::derive(move || Some(value.get()))))
1880 }
1881 }
1882
1883 impl<T> From<RwSignal<T>> for MaybeProp<T>
1884 where
1885 T: Send + Sync + Clone,
1886 {
1887 fn from(value: RwSignal<T>) -> Self {
1888 Self(Some(Signal::derive(move || Some(value.get()))))
1889 }
1890 }
1891
1892 impl<T> From<Memo<T>> for MaybeProp<T>
1893 where
1894 T: Send + Sync + Clone,
1895 {
1896 fn from(value: Memo<T>) -> Self {
1897 Self(Some(Signal::derive(move || Some(value.get()))))
1898 }
1899 }
1900
1901 impl<T> From<Signal<T>> for MaybeProp<T>
1902 where
1903 T: Send + Sync + Clone,
1904 {
1905 fn from(value: Signal<T>) -> Self {
1906 Self(Some(Signal::derive(move || Some(value.get()))))
1907 }
1908 }
1909
1910 impl From<&str> for MaybeProp<String> {
1911 fn from(value: &str) -> Self {
1912 Self(Some(Signal::from(Some(value.to_string()))))
1913 }
1914 }
1915
1916 impl<T> MaybeProp<T, LocalStorage> {
1917 pub fn derive_local(
1920 derived_signal: impl Fn() -> Option<T> + 'static,
1921 ) -> Self {
1922 Self(Some(Signal::derive_local(derived_signal)))
1923 }
1924 }
1925
1926 impl<T> FromLocal<T> for MaybeProp<T, LocalStorage> {
1927 fn from_local(value: T) -> Self {
1928 Self(Some(Signal::stored_local(Some(value))))
1929 }
1930 }
1931
1932 impl<T> FromLocal<Option<T>> for MaybeProp<T, LocalStorage> {
1933 fn from_local(value: Option<T>) -> Self {
1934 Self(Some(Signal::stored_local(value)))
1935 }
1936 }
1937
1938 #[allow(deprecated)]
1939 impl<T> From<MaybeSignal<Option<T>, LocalStorage>>
1940 for MaybeProp<T, LocalStorage>
1941 where
1942 T: Send + Sync,
1943 {
1944 fn from(value: MaybeSignal<Option<T>, LocalStorage>) -> Self {
1945 Self(Some(value.into()))
1946 }
1947 }
1948
1949 #[allow(deprecated)]
1950 impl<T> From<Option<MaybeSignal<Option<T>, LocalStorage>>>
1951 for MaybeProp<T, LocalStorage>
1952 where
1953 T: Send + Sync,
1954 {
1955 fn from(value: Option<MaybeSignal<Option<T>, LocalStorage>>) -> Self {
1956 Self(value.map(Into::into))
1957 }
1958 }
1959
1960 impl<T> From<ReadSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1961 where
1962 T: Send + Sync,
1963 {
1964 fn from(value: ReadSignal<Option<T>, LocalStorage>) -> Self {
1965 Self(Some(value.into()))
1966 }
1967 }
1968
1969 impl<T> From<RwSignal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1970 where
1971 T: Send + Sync,
1972 {
1973 fn from(value: RwSignal<Option<T>, LocalStorage>) -> Self {
1974 Self(Some(value.into()))
1975 }
1976 }
1977
1978 impl<T> From<Memo<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage>
1979 where
1980 T: Send + Sync,
1981 {
1982 fn from(value: Memo<Option<T>, LocalStorage>) -> Self {
1983 Self(Some(value.into()))
1984 }
1985 }
1986
1987 impl<T> From<Signal<Option<T>, LocalStorage>> for MaybeProp<T, LocalStorage> {
1988 fn from(value: Signal<Option<T>, LocalStorage>) -> Self {
1989 Self(Some(value))
1990 }
1991 }
1992
1993 impl<T> From<ReadSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
1994 where
1995 T: Send + Sync + Clone,
1996 {
1997 fn from(value: ReadSignal<T, LocalStorage>) -> Self {
1998 Self(Some(Signal::derive_local(move || Some(value.get()))))
1999 }
2000 }
2001
2002 impl<T> From<RwSignal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
2003 where
2004 T: Send + Sync + Clone,
2005 {
2006 fn from(value: RwSignal<T, LocalStorage>) -> Self {
2007 Self(Some(Signal::derive_local(move || Some(value.get()))))
2008 }
2009 }
2010
2011 impl<T> From<Memo<T, LocalStorage>> for MaybeProp<T, LocalStorage>
2012 where
2013 T: Send + Sync + Clone,
2014 {
2015 fn from(value: Memo<T, LocalStorage>) -> Self {
2016 Self(Some(Signal::derive_local(move || Some(value.get()))))
2017 }
2018 }
2019
2020 impl<T> From<Signal<T, LocalStorage>> for MaybeProp<T, LocalStorage>
2021 where
2022 T: Send + Sync + Clone,
2023 {
2024 fn from(value: Signal<T, LocalStorage>) -> Self {
2025 Self(Some(Signal::derive_local(move || Some(value.get()))))
2026 }
2027 }
2028
2029 impl From<&str> for MaybeProp<String, LocalStorage> {
2030 fn from(value: &str) -> Self {
2031 Self(Some(Signal::stored_local(Some(value.to_string()))))
2032 }
2033 }
2034
2035 pub enum SignalReadGuard<T: 'static, S: Storage<T>> {
2037 Read(ReadGuard<T, Plain<T>>),
2039 #[allow(clippy::type_complexity)]
2040 Memo(
2042 ReadGuard<T, Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>>,
2043 ),
2044 Owned(T),
2046 }
2047
2048 impl<T: 'static + std::fmt::Debug, S: Storage<T> + std::fmt::Debug>
2049 std::fmt::Debug for SignalReadGuard<T, S>
2050 where
2051 <S as Storage<T>>::Wrapped: std::fmt::Debug,
2052 {
2053 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2054 match self {
2055 Self::Read(arg0) => f.debug_tuple("Read").field(arg0).finish(),
2056 Self::Memo(arg0) => f.debug_tuple("Memo").field(arg0).finish(),
2057 Self::Owned(arg0) => {
2058 f.debug_tuple("Owned").field(arg0).finish()
2059 }
2060 }
2061 }
2062 }
2063
2064 impl<T, S> Clone for SignalReadGuard<T, S>
2065 where
2066 S: Storage<T>,
2067 T: Clone,
2068 Plain<T>: Clone,
2069 Mapped<Plain<Option<<S as Storage<T>>::Wrapped>>, T>: Clone,
2070 {
2071 fn clone(&self) -> Self {
2072 match self {
2073 SignalReadGuard::Read(i) => SignalReadGuard::Read(i.clone()),
2074 SignalReadGuard::Memo(i) => SignalReadGuard::Memo(i.clone()),
2075 SignalReadGuard::Owned(i) => SignalReadGuard::Owned(i.clone()),
2076 }
2077 }
2078 }
2079
2080 impl<T, S> Deref for SignalReadGuard<T, S>
2081 where
2082 S: Storage<T>,
2083 {
2084 type Target = T;
2085 fn deref(&self) -> &Self::Target {
2086 match self {
2087 SignalReadGuard::Read(i) => i,
2088 SignalReadGuard::Memo(i) => i,
2089 SignalReadGuard::Owned(i) => i,
2090 }
2091 }
2092 }
2093
2094 impl<T, S> Borrow<T> for SignalReadGuard<T, S>
2095 where
2096 S: Storage<T>,
2097 {
2098 fn borrow(&self) -> &T {
2099 self.deref()
2100 }
2101 }
2102
2103 impl<T, S> PartialEq<T> for SignalReadGuard<T, S>
2104 where
2105 S: Storage<T>,
2106 T: PartialEq,
2107 {
2108 fn eq(&self, other: &T) -> bool {
2109 self.deref() == other
2110 }
2111 }
2112
2113 impl<T, S> Display for SignalReadGuard<T, S>
2114 where
2115 S: Storage<T>,
2116 T: Display,
2117 {
2118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2119 Display::fmt(&**self, f)
2120 }
2121 }
2122}
2123
2124pub mod write {
2126 use crate::{
2127 owner::{ArenaItem, Storage, SyncStorage},
2128 signal::{ArcRwSignal, ArcWriteSignal, RwSignal, WriteSignal},
2129 traits::Set,
2130 };
2131
2132 pub trait IntoSignalSetter<T, S>: Sized {
2134 fn into_signal_setter(self) -> SignalSetter<T, S>;
2136 }
2137
2138 impl<F, T, S> IntoSignalSetter<T, S> for F
2139 where
2140 F: Fn(T) + 'static + Send + Sync,
2141 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
2142 {
2143 fn into_signal_setter(self) -> SignalSetter<T, S> {
2144 SignalSetter::map(self)
2145 }
2146 }
2147
2148 #[derive(Debug, PartialEq, Eq)]
2182 pub struct SignalSetter<T, S = SyncStorage>
2183 where
2184 T: 'static,
2185 {
2186 inner: SignalSetterTypes<T, S>,
2187 #[cfg(any(debug_assertions, leptos_debuginfo))]
2188 defined_at: &'static std::panic::Location<'static>,
2189 }
2190
2191 impl<T, S> Clone for SignalSetter<T, S> {
2192 fn clone(&self) -> Self {
2193 *self
2194 }
2195 }
2196
2197 impl<T: Default + 'static, S> Default for SignalSetter<T, S> {
2198 #[track_caller]
2199 fn default() -> Self {
2200 Self {
2201 inner: SignalSetterTypes::Default,
2202 #[cfg(any(debug_assertions, leptos_debuginfo))]
2203 defined_at: std::panic::Location::caller(),
2204 }
2205 }
2206 }
2207
2208 impl<T, S> Copy for SignalSetter<T, S> {}
2209
2210 impl<T, S> Set for SignalSetter<T, S>
2211 where
2212 T: 'static,
2213 S: Storage<ArcWriteSignal<T>> + Storage<Box<dyn Fn(T) + Send + Sync>>,
2214 {
2215 type Value = T;
2216
2217 fn set(&self, new_value: Self::Value) {
2218 match self.inner {
2219 SignalSetterTypes::Default => {}
2220 SignalSetterTypes::Write(w) => w.set(new_value),
2221 SignalSetterTypes::Mapped(s) => {
2222 s.try_with_value(|setter| setter(new_value));
2223 }
2224 }
2225 }
2226
2227 fn try_set(&self, new_value: Self::Value) -> Option<Self::Value> {
2228 match self.inner {
2229 SignalSetterTypes::Default => Some(new_value),
2230 SignalSetterTypes::Write(w) => w.try_set(new_value),
2231 SignalSetterTypes::Mapped(s) => {
2232 let mut new_value = Some(new_value);
2233
2234 let _ = s.try_with_value(|setter| {
2235 setter(new_value.take().unwrap())
2236 });
2237
2238 new_value
2239 }
2240 }
2241 }
2242 }
2243
2244 impl<T, S> SignalSetter<T, S>
2245 where
2246 S: Storage<Box<dyn Fn(T) + Send + Sync>>,
2247 {
2248 #[track_caller]
2250 pub fn map(mapped_setter: impl Fn(T) + Send + Sync + 'static) -> Self {
2251 Self {
2252 inner: SignalSetterTypes::Mapped(ArenaItem::new_with_storage(
2253 Box::new(mapped_setter),
2254 )),
2255 #[cfg(any(debug_assertions, leptos_debuginfo))]
2256 defined_at: std::panic::Location::caller(),
2257 }
2258 }
2259 }
2260
2261 impl<T, S> From<WriteSignal<T, S>> for SignalSetter<T, S> {
2262 #[track_caller]
2263 fn from(value: WriteSignal<T, S>) -> Self {
2264 Self {
2265 inner: SignalSetterTypes::Write(value),
2266 #[cfg(any(debug_assertions, leptos_debuginfo))]
2267 defined_at: std::panic::Location::caller(),
2268 }
2269 }
2270 }
2271
2272 impl<T, S> From<RwSignal<T, S>> for SignalSetter<T, S>
2273 where
2274 T: Send + Sync + 'static,
2275 S: Storage<ArcRwSignal<T>> + Storage<ArcWriteSignal<T>>,
2276 {
2277 #[track_caller]
2278 fn from(value: RwSignal<T, S>) -> Self {
2279 Self {
2280 inner: SignalSetterTypes::Write(value.write_only()),
2281 #[cfg(any(debug_assertions, leptos_debuginfo))]
2282 defined_at: std::panic::Location::caller(),
2283 }
2284 }
2285 }
2286
2287 enum SignalSetterTypes<T, S = SyncStorage>
2288 where
2289 T: 'static,
2290 {
2291 Write(WriteSignal<T, S>),
2292 Mapped(ArenaItem<Box<dyn Fn(T) + Send + Sync>, S>),
2293 Default,
2294 }
2295
2296 impl<T, S> Clone for SignalSetterTypes<T, S> {
2297 fn clone(&self) -> Self {
2298 *self
2299 }
2300 }
2301
2302 impl<T, S> Copy for SignalSetterTypes<T, S> {}
2303
2304 impl<T, S> core::fmt::Debug for SignalSetterTypes<T, S>
2305 where
2306 T: core::fmt::Debug,
2307 S: core::fmt::Debug,
2308 {
2309 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2310 match self {
2311 Self::Write(arg0) => {
2312 f.debug_tuple("WriteSignal").field(arg0).finish()
2313 }
2314 Self::Mapped(_) => f.debug_tuple("Mapped").finish(),
2315 Self::Default => {
2316 f.debug_tuple("SignalSetter<Default>").finish()
2317 }
2318 }
2319 }
2320 }
2321
2322 impl<T, S> PartialEq for SignalSetterTypes<T, S>
2323 where
2324 T: PartialEq,
2325 {
2326 fn eq(&self, other: &Self) -> bool {
2327 match (self, other) {
2328 (Self::Write(l0), Self::Write(r0)) => l0 == r0,
2329 (Self::Mapped(l0), Self::Mapped(r0)) => std::ptr::eq(l0, r0),
2330 _ => false,
2331 }
2332 }
2333 }
2334
2335 impl<T, S> Eq for SignalSetterTypes<T, S> where T: PartialEq {}
2336}