allow raw elements if they include a dash

This commit is contained in:
Evan Almloff committed 2023-03-19 20:37:40 -05:00
1 parent 46cc07e048
commit 209a55da69
5 files changed
+141 -18

No files matched your search

+95 -12
View File
@@ -1,9 +1,12 @@
use std::fmt::{Display, Formatter};
use super::*;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
parse::{Parse, ParseBuffer, ParseStream},
punctuated::Punctuated,
Error, Expr, Ident, LitStr, Result, Token,
};
@@ -12,7 +15,7 @@ use syn::{
// =======================================
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub struct Element {
pub name: Ident,
pub name: ElementName,
pub key: Option<IfmtInput>,
pub attributes: Vec<ElementAttrNamed>,
pub children: Vec<BodyNode>,
@@ -22,7 +25,7 @@ pub struct Element {
impl Parse for Element {
fn parse(stream: ParseStream) -> Result<Self> {
let el_name = Ident::parse(stream)?;
let el_name = ElementName::parse(stream)?;
// parse the guts
let content: ParseBuffer;
@@ -181,7 +184,7 @@ impl ToTokens for Element {
tokens.append_all(quote! {
__cx.element(
dioxus_elements::#name,
#name,
__cx.bump().alloc([ #(#listeners),* ]),
__cx.bump().alloc([ #(#attr),* ]),
__cx.bump().alloc([ #(#children),* ]),
@@ -191,6 +194,60 @@ impl ToTokens for Element {
}
}
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub enum ElementName {
Ident(Ident),
Custom(String),
}
impl ElementName {
pub(crate) fn tag_name(&self) -> TokenStream2 {
match self {
ElementName::Ident(i) => quote! { dioxus_elements::#i::TAG_NAME },
ElementName::Custom(s) => quote! { #s },
}
}
}
impl PartialEq<&str> for ElementName {
fn eq(&self, other: &&str) -> bool {
match self {
ElementName::Ident(i) => i == *other,
ElementName::Custom(s) => s == *other,
}
}
}
impl Display for ElementName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ElementName::Ident(i) => write!(f, "{}", i),
ElementName::Custom(s) => write!(f, "{}", s),
}
}
}
impl Parse for ElementName {
fn parse(stream: ParseStream) -> Result<Self> {
let raw = Punctuated::<Ident, Token![-]>::parse_separated_nonempty(stream)?;
if raw.len() == 1 {
Ok(ElementName::Ident(raw.into_iter().next().unwrap()))
} else {
let tag = raw.into_iter().map(|ident| ident.to_string()).collect::<Vec<_>>().join("-");
Ok(ElementName::Custom(tag))
}
}
}
impl ToTokens for ElementName {
fn to_tokens(&self, tokens: &mut TokenStream2) {
match self {
ElementName::Ident(i) => tokens.append_all(quote! { dioxus_elements::#i }),
ElementName::Custom(s) => tokens.append_all(quote! { #s }),
}
}
}
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub enum ElementAttr {
/// `attribute: "value"`
@@ -234,7 +291,7 @@ impl ElementAttr {
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub struct ElementAttrNamed {
pub el_name: Ident,
pub el_name: ElementName,
pub attr: ElementAttr,
}
@@ -242,24 +299,48 @@ impl ToTokens for ElementAttrNamed {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let ElementAttrNamed { el_name, attr } = self;
tokens.append_all(match attr {
let ns = |name| match el_name {
ElementName::Ident(i) => quote! { dioxus_elements::#i::#name.1 },
ElementName::Custom(_) => quote! { None },
};
let volitile = |name| match el_name {
ElementName::Ident(_) => quote! { #el_name::#name.2 },
ElementName::Custom(_) => quote! { false },
};
let attribute=|name: &Ident| match el_name{
ElementName::Ident(_) => quote! { #el_name::#name.0 },
ElementName::Custom(_) => {
let as_string=name.to_string();
quote!(#as_string)
}
};
let attribute=
match attr {
ElementAttr::AttrText { name, value } => {
let ns = ns(name);
let volitile = volitile(name);
let attribute=attribute(name);
quote! {
__cx.attr(
dioxus_elements::#el_name::#name.0,
#attribute,
#value,
dioxus_elements::#el_name::#name.1,
dioxus_elements::#el_name::#name.2
#ns,
#volitile
)
}
}
ElementAttr::AttrExpression { name, value } => {
let ns = ns(name);
let volitile = volitile(name);
let attribute=attribute(name);
quote! {
__cx.attr(
dioxus_elements::#el_name::#name.0,
#attribute,
#value,
dioxus_elements::#el_name::#name.1,
dioxus_elements::#el_name::#name.2
#ns,
#volitile
)
}
}
@@ -288,7 +369,9 @@ impl ToTokens for ElementAttrNamed {
dioxus_elements::events::#name(__cx, #tokens)
}
}
});
};
tokens.append_all(attribute);
}
}