Destructuring `let` (0.7) (#2655)

* Use `let()` syntax for bindings

This lets users use destructuring when binding more complex values, and we also get better IDE support.

* Update rstml
This commit is contained in:
Lucas Åström 2024-06-29 22:15:39 +02:00 committed by Greg Johnston
parent c76208aad0
commit ce4fe632a2
3 changed files with 29 additions and 9 deletions

View File

@ -20,7 +20,7 @@ syn = { version = "2", features = [
"printing", "printing",
] } ] }
quote = "1" quote = "1"
rstml = "0.11.0" rstml = "0.11.2"
proc-macro2 = { version = "1", features = ["span-locations", "nightly"] } proc-macro2 = { version = "1", features = ["span-locations", "nightly"] }
parking_lot = "0.12" parking_lot = "0.12"
walkdir = "2" walkdir = "2"

View File

@ -22,7 +22,7 @@ proc-macro-error = { version = "1", default-features = false }
proc-macro2 = "1" proc-macro2 = "1"
quote = "1" quote = "1"
syn = { version = "2", features = ["full"] } syn = { version = "2", features = ["full"] }
rstml = "0.11.0" rstml = "0.11.2"
leptos_hot_reload = { workspace = true } leptos_hot_reload = { workspace = true }
server_fn_macro = { workspace = true } server_fn_macro = { workspace = true }
convert_case = "0.6.0" convert_case = "0.6.0"

View File

@ -2,9 +2,9 @@ use super::{fragment_to_tokens, TagType};
use crate::view::attribute_absolute; use crate::view::attribute_absolute;
use proc_macro2::{Ident, TokenStream, TokenTree}; use proc_macro2::{Ident, TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned}; use quote::{format_ident, quote, quote_spanned};
use rstml::node::{NodeAttribute, NodeBlock, NodeElement}; use rstml::node::{KeyedAttributeValue, NodeAttribute, NodeBlock, NodeElement, NodeName};
use std::collections::HashMap; use std::collections::HashMap;
use syn::{spanned::Spanned, Expr, ExprRange, RangeLimits, Stmt}; use syn::{spanned::Spanned, Expr, ExprRange, RangeLimits, Stmt, ExprPath};
pub(crate) fn component_to_tokens( pub(crate) fn component_to_tokens(
node: &NodeElement, node: &NodeElement,
@ -56,7 +56,7 @@ pub(crate) fn component_to_tokens(
.filter(|(idx, attr)| { .filter(|(idx, attr)| {
idx < &spread_marker && { idx < &spread_marker && {
let attr_key = attr.key.to_string(); let attr_key = attr.key.to_string();
!attr_key.starts_with("let:") !is_attr_let(&attr.key)
&& !attr_key.starts_with("clone:") && !attr_key.starts_with("clone:")
&& !attr_key.starts_with("class:") && !attr_key.starts_with("class:")
&& !attr_key.starts_with("style:") && !attr_key.starts_with("style:")
@ -86,10 +86,20 @@ pub(crate) fn component_to_tokens(
let items_to_bind = attrs let items_to_bind = attrs
.clone() .clone()
.filter_map(|attr| { .filter_map(|attr| {
attr.key if !is_attr_let(&attr.key) {
.to_string() return None;
.strip_prefix("let:") }
.map(|ident| format_ident!("{ident}", span = attr.key.span()))
let KeyedAttributeValue::Binding(binding) = &attr.possible_value else {
if let Some(ident) = attr.key.to_string().strip_prefix("let:") {
let ident1 = format_ident!("{ident}", span = attr.key.span());
return Some(quote! { #ident1 });
} else {
return None;
}
};
let inputs = &binding.inputs;
Some(quote! { #inputs })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -286,3 +296,13 @@ pub(crate) fn component_to_tokens(
component component
} }
fn is_attr_let(key: &NodeName) -> bool {
if key.to_string().starts_with("let:") {
true
} else if let NodeName::Path(ExprPath { path, .. }) = key {
path.segments.len() == 1 && path.segments[0].ident == "let"
} else {
false
}
}