1use oco_ref::Oco;
2use std::sync::Arc;
3use tachys::prelude::IntoAttributeValue;
4
5#[derive(Clone)]
8pub struct TextProp(Arc<dyn Fn() -> Oco<'static, str> + Send + Sync>);
9
10impl TextProp {
11 #[inline(always)]
13 pub fn get(&self) -> Oco<'static, str> {
14 (self.0)()
15 }
16}
17
18impl core::fmt::Debug for TextProp {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 f.debug_tuple("TextProp").finish()
21 }
22}
23
24impl From<String> for TextProp {
25 fn from(s: String) -> Self {
26 let s: Oco<'_, str> = Oco::Counted(Arc::from(s));
27 TextProp(Arc::new(move || s.clone()))
28 }
29}
30
31impl From<&'static str> for TextProp {
32 fn from(s: &'static str) -> Self {
33 let s: Oco<'_, str> = s.into();
34 TextProp(Arc::new(move || s.clone()))
35 }
36}
37
38impl From<Arc<str>> for TextProp {
39 fn from(s: Arc<str>) -> Self {
40 let s: Oco<'_, str> = s.into();
41 TextProp(Arc::new(move || s.clone()))
42 }
43}
44
45impl From<Oco<'static, str>> for TextProp {
46 fn from(s: Oco<'static, str>) -> Self {
47 TextProp(Arc::new(move || s.clone()))
48 }
49}
50
51impl<F, S> From<F> for TextProp
62where
63 F: Fn() -> S + 'static + Send + Sync,
64 S: Into<Oco<'static, str>>,
65{
66 #[inline(always)]
67 fn from(s: F) -> Self {
68 TextProp(Arc::new(move || s().into()))
69 }
70}
71
72impl Default for TextProp {
73 fn default() -> Self {
74 Self(Arc::new(|| Oco::Borrowed("")))
75 }
76}
77
78impl IntoAttributeValue for TextProp {
79 type Output = Arc<dyn Fn() -> Oco<'static, str> + Send + Sync>;
80
81 fn into_attribute_value(self) -> Self::Output {
82 self.0
83 }
84}
85
86#[allow(unused)]
87macro_rules! textprop_reactive {
88 ($name:ident, <$($gen:ident),*>, $v:ty, $( $where_clause:tt )*) =>
89 {
90 #[allow(deprecated)]
91 impl<$($gen),*> From<$name<$($gen),*>> for TextProp
92 where
93 $v: Into<Oco<'static, str>> + Clone + Send + Sync + 'static,
94 $($where_clause)*
95 {
96 #[inline(always)]
97 fn from(s: $name<$($gen),*>) -> Self {
98 TextProp(Arc::new(move || s.get().into()))
99 }
100 }
101 };
102}
103
104#[cfg(not(all(feature = "nightly", rustc_nightly)))]
105mod stable {
106 use super::TextProp;
107 use oco_ref::Oco;
108 #[allow(deprecated)]
109 use reactive_graph::wrappers::read::MaybeSignal;
110 use reactive_graph::{
111 computed::{ArcMemo, Memo},
112 owner::Storage,
113 signal::{ArcReadSignal, ArcRwSignal, ReadSignal, RwSignal},
114 traits::Get,
115 wrappers::read::{ArcSignal, Signal},
116 };
117 use std::sync::Arc;
118
119 textprop_reactive!(
120 RwSignal,
121 <V, S>,
122 V,
123 RwSignal<V, S>: Get<Value = V>,
124 S: Storage<V> + Storage<Option<V>>,
125 S: Send + Sync + 'static,
126 );
127 textprop_reactive!(
128 ReadSignal,
129 <V, S>,
130 V,
131 ReadSignal<V, S>: Get<Value = V>,
132 S: Storage<V> + Storage<Option<V>>,
133 S: Send + Sync + 'static,
134 );
135 textprop_reactive!(
136 Memo,
137 <V, S>,
138 V,
139 Memo<V, S>: Get<Value = V>,
140 S: Storage<V> + Storage<Option<V>>,
141 S: Send + Sync + 'static,
142 );
143 textprop_reactive!(
144 Signal,
145 <V, S>,
146 V,
147 Signal<V, S>: Get<Value = V>,
148 S: Storage<V> + Storage<Option<V>>,
149 S: Send + Sync + 'static,
150 );
151 textprop_reactive!(
152 MaybeSignal,
153 <V, S>,
154 V,
155 MaybeSignal<V, S>: Get<Value = V>,
156 S: Storage<V> + Storage<Option<V>>,
157 S: Send + Sync + 'static,
158 );
159 textprop_reactive!(ArcRwSignal, <V>, V, ArcRwSignal<V>: Get<Value = V>);
160 textprop_reactive!(ArcReadSignal, <V>, V, ArcReadSignal<V>: Get<Value = V>);
161 textprop_reactive!(ArcMemo, <V>, V, ArcMemo<V>: Get<Value = V>);
162 textprop_reactive!(ArcSignal, <V>, V, ArcSignal<V>: Get<Value = V>);
163}
164
165pub trait OptionTextPropExt {
167 fn get(&self) -> Option<Oco<'static, str>>;
169}
170
171impl OptionTextPropExt for Option<TextProp> {
172 fn get(&self) -> Option<Oco<'static, str>> {
173 self.as_ref().map(|text_prop| text_prop.get())
174 }
175}