Skip to main content

euv_core/reactive/cast/
impl.rs

1use crate::*;
2
3/// Converts a static `String` into a text attribute value.
4impl From<String> for AttributeValue {
5    /// Converts this string into an `AttributeValue::Text`.
6    ///
7    /// # Returns
8    ///
9    /// - `AttributeValue` - A text attribute value containing this string.
10    fn from(value: String) -> Self {
11        AttributeValue::Text(value)
12    }
13}
14
15/// Converts a string slice into a text attribute value.
16impl From<&str> for AttributeValue {
17    /// Converts this string slice into an `AttributeValue::Text`.
18    ///
19    /// # Returns
20    ///
21    /// - `AttributeValue` - A text attribute value containing the owned string.
22    fn from(value: &str) -> Self {
23        AttributeValue::Text(value.to_string())
24    }
25}
26
27/// Converts a string signal into a reactive attribute value.
28impl From<Signal<String>> for AttributeValue {
29    /// Converts this string signal into an `AttributeValue::Signal`.
30    ///
31    /// # Returns
32    ///
33    /// - `AttributeValue` - A signal-backed attribute value.
34    fn from(signal: Signal<String>) -> Self {
35        AttributeValue::Signal(signal)
36    }
37}
38
39/// Converts a mutable bool signal into a reactive attribute value.
40///
41/// The signal is mapped to a `Signal<String>` that yields `"true"` or `"false"`,
42/// enabling boolean attributes like `checked` to reactively update the DOM.
43impl From<Signal<bool>> for AttributeValue {
44    /// Converts this bool signal into an `AttributeValue` via string mapping.
45    ///
46    /// # Returns
47    ///
48    /// - `AttributeValue` - A signal-backed attribute value yielding `"true"` or `"false"`.
49    fn from(signal: Signal<bool>) -> Self {
50        AttributeValue::bool_to_attr(signal)
51    }
52}
53
54/// Converts a `bool` into a dynamic attribute value.
55///
56/// Stored as `AttributeValue::Dynamic("true"/"false")` so components can
57/// extract the original boolean via `try_get_typed_prop`.
58impl From<bool> for AttributeValue {
59    /// Converts this boolean into an `AttributeValue::Dynamic`.
60    ///
61    /// # Returns
62    ///
63    /// - `AttributeValue` - A dynamic attribute value containing the boolean string.
64    fn from(value: bool) -> Self {
65        AttributeValue::Dynamic(value.to_string())
66    }
67}
68
69/// Converts an `i32` into a dynamic attribute value.
70///
71/// Stored as `AttributeValue::Dynamic` so components can extract the
72/// original integer via `try_get_typed_prop`.
73impl From<i32> for AttributeValue {
74    /// Converts this integer into an `AttributeValue::Dynamic`.
75    ///
76    /// # Returns
77    ///
78    /// - `AttributeValue` - A dynamic attribute value containing the integer string.
79    fn from(value: i32) -> Self {
80        AttributeValue::Dynamic(value.to_string())
81    }
82}
83
84/// Converts an `f64` into a dynamic attribute value.
85///
86/// Stored as `AttributeValue::Dynamic` so components can extract the
87/// original float via `try_get_typed_prop`.
88impl From<f64> for AttributeValue {
89    /// Converts this float into an `AttributeValue::Dynamic`.
90    ///
91    /// # Returns
92    ///
93    /// - `AttributeValue` - A dynamic attribute value containing the float string.
94    fn from(value: f64) -> Self {
95        AttributeValue::Dynamic(value.to_string())
96    }
97}
98
99/// Converts a CSS class reference into an attribute value.
100impl From<Css> for AttributeValue {
101    /// Converts this CSS class into an `AttributeValue::Css`.
102    ///
103    /// # Returns
104    ///
105    /// - `AttributeValue` - A CSS class attribute value.
106    fn from(css: Css) -> Self {
107        AttributeValue::Css(css)
108    }
109}
110
111/// Converts a reference to a CSS class into an attribute value by cloning.
112impl From<&'static Css> for AttributeValue {
113    /// Converts this CSS class reference into an `AttributeValue::Css` by cloning.
114    ///
115    /// # Returns
116    ///
117    /// - `AttributeValue` - A CSS class attribute value.
118    fn from(css: &'static Css) -> Self {
119        AttributeValue::Css(css.clone())
120    }
121}
122
123/// Converts a closure into a callback attribute value.
124impl<F> From<F> for AttributeValue
125where
126    F: FnMut(Event) + 'static,
127{
128    /// Wraps this closure into an `AttributeValue::Event` with a generic "callback" event name.
129    ///
130    /// # Returns
131    ///
132    /// - `AttributeValue` - An event attribute value wrapping this closure.
133    fn from(closure: F) -> Self {
134        AttributeValue::Event(NativeEventHandler::create(CALLBACK_EVENT_NAME, closure))
135    }
136}
137
138/// Converts an owned event handler into a callback attribute value.
139///
140/// Re-wraps the handler with a generic "callback" event name so that
141/// subsequent `EventAdapter::into_attribute` calls can override it with
142/// the correct DOM event type.
143impl From<NativeEventHandler> for AttributeValue {
144    /// Converts this event handler into an `AttributeValue::Event`.
145    ///
146    /// # Returns
147    ///
148    /// - `AttributeValue` - An event attribute value with a generic callback event name.
149    fn from(handler: NativeEventHandler) -> Self {
150        AttrValueAdapter::new(handler).into()
151    }
152}
153
154/// Converts an optional event handler into a callback attribute value.
155///
156/// Re-wraps a `Some` handler with a generic "callback" event name so that
157/// subsequent `EventAdapter::into_attribute` calls can override it with
158/// the correct DOM event type.
159impl From<Option<NativeEventHandler>> for AttributeValue {
160    /// Converts this optional handler into an `AttributeValue::Event` or `AttributeValue::Text` if `None`.
161    ///
162    /// # Returns
163    ///
164    /// - `AttributeValue` - An event attribute value if `Some`, otherwise an empty text attribute.
165    fn from(handler: Option<NativeEventHandler>) -> Self {
166        match handler {
167            Some(event_handler) => AttrValueAdapter::new(event_handler).into(),
168            None => AttributeValue::Text(String::new()),
169        }
170    }
171}
172
173/// Converts an optional string signal into a reactive or empty attribute value.
174///
175/// `Some(signal)` becomes `AttributeValue::Signal`, `None` becomes
176/// `AttributeValue::Text(String::new())`. This supports component props
177/// that use `Option<Signal<String>>` for optional reactive attributes.
178impl From<Option<Signal<String>>> for AttributeValue {
179    fn from(signal: Option<Signal<String>>) -> Self {
180        match signal {
181            Some(string_signal) => AttributeValue::Signal(string_signal),
182            None => AttributeValue::Text(String::new()),
183        }
184    }
185}