examples: upgrade to new version of dioxus core.
also add the inline_props macro
This commit is contained in:
1 parent
21e00c114e
commit
cda759c659
41 files changed
+556
-253
No files matched your search
@@ -0,0 +1,102 @@
|
||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
token, Block, FnArg, Generics, Ident, Result, ReturnType, Token, Visibility,
|
||||
};
|
||||
|
||||
pub struct InlinePropsBody {
|
||||
pub vis: syn::Visibility,
|
||||
pub fn_token: Token![fn],
|
||||
pub ident: Ident,
|
||||
pub cx_token: Ident,
|
||||
pub generics: Generics,
|
||||
pub paren_token: token::Paren,
|
||||
pub inputs: Punctuated<FnArg, Token![,]>,
|
||||
// pub fields: FieldsNamed,
|
||||
pub output: ReturnType,
|
||||
pub block: Box<Block>,
|
||||
}
|
||||
|
||||
/// The custom rusty variant of parsing rsx!
|
||||
impl Parse for InlinePropsBody {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let vis: Visibility = input.parse()?;
|
||||
|
||||
let fn_token = input.parse()?;
|
||||
let ident = input.parse()?;
|
||||
let generics = input.parse()?;
|
||||
|
||||
let content;
|
||||
let paren_token = syn::parenthesized!(content in input);
|
||||
|
||||
let cx_token: Ident = content.parse()?;
|
||||
let _: Token![:] = content.parse()?;
|
||||
let _: Ident = content.parse()?;
|
||||
let _: Result<Token![,]> = content.parse();
|
||||
|
||||
let inputs = syn::punctuated::Punctuated::parse_terminated(&content)?;
|
||||
|
||||
let output = input.parse()?;
|
||||
|
||||
let block = input.parse()?;
|
||||
|
||||
Ok(Self {
|
||||
vis,
|
||||
fn_token,
|
||||
ident,
|
||||
generics,
|
||||
paren_token,
|
||||
inputs,
|
||||
output,
|
||||
block,
|
||||
cx_token,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialize the same way, regardless of flavor
|
||||
impl ToTokens for InlinePropsBody {
|
||||
fn to_tokens(&self, out_tokens: &mut TokenStream2) {
|
||||
let Self {
|
||||
vis,
|
||||
ident,
|
||||
generics,
|
||||
inputs,
|
||||
output,
|
||||
block,
|
||||
cx_token,
|
||||
..
|
||||
} = self;
|
||||
|
||||
let fields = inputs.iter().map(|f| {
|
||||
quote! { #vis #f }
|
||||
});
|
||||
|
||||
let struct_name = Ident::new(&format!("{}Props", ident), Span::call_site());
|
||||
|
||||
let field_names = inputs.iter().filter_map(|f| match f {
|
||||
FnArg::Receiver(_) => todo!(),
|
||||
FnArg::Typed(t) => Some(&t.pat),
|
||||
});
|
||||
|
||||
let modifiers = if generics.params.is_empty() {
|
||||
quote! { #[derive(Props, PartialEq)] }
|
||||
} else {
|
||||
quote! { #[derive(PartialEq)] }
|
||||
};
|
||||
|
||||
out_tokens.append_all(quote! {
|
||||
#modifiers
|
||||
#vis struct #struct_name #generics {
|
||||
#(#fields),*
|
||||
}
|
||||
|
||||
#vis fn #ident #generics (#cx_token: Scope<#struct_name>) #output {
|
||||
let #struct_name { #(#field_names),* } = &cx.props;
|
||||
#block
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ use proc_macro::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
pub(crate) mod htm;
|
||||
pub(crate) mod ifmt;
|
||||
pub(crate) mod inlineprops;
|
||||
pub(crate) mod props;
|
||||
pub(crate) mod router;
|
||||
pub(crate) mod rsx;
|
||||
@@ -214,3 +214,37 @@ pub fn routable_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
let input = parse_macro_input!(input as Routable);
|
||||
routable_derive_impl(input).into()
|
||||
}
|
||||
|
||||
/// Derive props for a component within the component definition.
|
||||
///
|
||||
/// This macro provides a simple transformation from `Scope<{}>` to `Scope<P>`,
|
||||
/// removing some boilerplate when defining props.
|
||||
///
|
||||
/// You don't *need* to use this macro at all, but it can be helpful in cases where
|
||||
/// you would be repeating a lot of the usual Rust boilerplate.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #[inline_props]
|
||||
/// fn app(cx: Scope<{ bob: String }>) -> Element {
|
||||
/// cx.render(rsx!("hello, {bob}"))
|
||||
/// }
|
||||
///
|
||||
/// // is equivalent to
|
||||
///
|
||||
/// #[derive(PartialEq, Props)]
|
||||
/// struct AppProps {
|
||||
/// bob: String,
|
||||
/// }
|
||||
///
|
||||
/// fn app(cx: Scope<AppProps>) -> Element {
|
||||
/// cx.render(rsx!("hello, {bob}"))
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn inline_props(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
||||
match syn::parse::<inlineprops::InlinePropsBody>(s) {
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
Ok(s) => s.to_token_stream().into(),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user