diff --git a/crates/html-macro/src/parser/open_tag.rs b/crates/html-macro/src/parser/open_tag.rs
index 3ccafe4e..e022cbf8 100644
--- a/crates/html-macro/src/parser/open_tag.rs
+++ b/crates/html-macro/src/parser/open_tag.rs
@@ -103,6 +103,11 @@ fn create_valid_node(
tokens.push(add_closure);
}
_ => {
+ // NOTE: The `AttributeValue`'s documentation mentions that contributors can search
+ // for `#value.into()` to find where the `AttributeValue`'s `From` implementation
+ // is used.
+ // So, if we change this code such that it no longer says `#value.into()`, we
+ // should update the `AttributeValue's` `From` implementation's documentation.
let insert_attribute = quote! {
#var_name_node.as_velement_mut().expect("Not an element")
.attrs.insert(#key.to_string(), #value.into());
diff --git a/crates/virtual-node/src/velement/attribute_value.rs b/crates/virtual-node/src/velement/attribute_value.rs
index 3767fa9c..8c38ddd2 100644
--- a/crates/virtual-node/src/velement/attribute_value.rs
+++ b/crates/virtual-node/src/velement/attribute_value.rs
@@ -64,65 +64,76 @@ impl Into for AttributeValue {
}
}
-impl From for AttributeValue {
- fn from(s: String) -> Self {
- AttributeValue::String(s)
+mod from_impls {
+ //! These `From` implementations are used by the `html-macro` to convert an arbitrary expression
+ //! into an [`AttributeValue`].
+ //! Relying on the `From` impl allows us to create an `AttributeValue` without needing the
+ //! `AttributeValue` type to be in scope. This means that the generated macro code does not
+ //! require `AttributeValue` to be in scope.
+ //! To find this use case, search for `#value.into()` within the `crates/html-macro` crate.
+
+ use super::*;
+
+ impl From for AttributeValue {
+ fn from(s: String) -> Self {
+ AttributeValue::String(s)
+ }
}
-}
-impl From<&String> for AttributeValue {
- fn from(s: &String) -> Self {
- AttributeValue::String(s.to_string())
+ impl From<&String> for AttributeValue {
+ fn from(s: &String) -> Self {
+ AttributeValue::String(s.to_string())
+ }
}
-}
-impl From<&str> for AttributeValue {
- fn from(s: &str) -> Self {
- AttributeValue::String(s.to_string())
+ impl From<&str> for AttributeValue {
+ fn from(s: &str) -> Self {
+ AttributeValue::String(s.to_string())
+ }
}
-}
-impl, const N: usize> From<[S; N]> for AttributeValue {
- fn from(vals: [S; N]) -> Self {
- let mut combined = "".to_string();
+ impl, const N: usize> From<[S; N]> for AttributeValue {
+ fn from(vals: [S; N]) -> Self {
+ let mut combined = "".to_string();
- for (idx, val) in vals.iter().enumerate() {
- if idx != 0 {
- combined += " ";
+ for (idx, val) in vals.iter().enumerate() {
+ if idx != 0 {
+ combined += " ";
+ }
+
+ combined += val.as_ref();
}
- combined += val.as_ref();
+ AttributeValue::String(combined)
}
-
- AttributeValue::String(combined)
}
-}
-impl> From> for AttributeValue {
- fn from(vals: Vec) -> Self {
- let mut combined = "".to_string();
+ impl> From> for AttributeValue {
+ fn from(vals: Vec) -> Self {
+ let mut combined = "".to_string();
- for (idx, val) in vals.iter().enumerate() {
- if idx != 0 {
- combined += " ";
+ for (idx, val) in vals.iter().enumerate() {
+ if idx != 0 {
+ combined += " ";
+ }
+
+ combined += val.as_ref();
}
- combined += val.as_ref();
+ AttributeValue::String(combined)
}
-
- AttributeValue::String(combined)
}
-}
-impl From for AttributeValue {
- fn from(b: bool) -> Self {
- AttributeValue::Bool(b)
+ impl From for AttributeValue {
+ fn from(b: bool) -> Self {
+ AttributeValue::Bool(b)
+ }
}
-}
-impl From<&bool> for AttributeValue {
- fn from(b: &bool) -> Self {
- AttributeValue::Bool(*b)
+ impl From<&bool> for AttributeValue {
+ fn from(b: &bool) -> Self {
+ AttributeValue::Bool(*b)
+ }
}
}