Initial commit

This commit is contained in:
DavidOnTop 2024-06-15 11:22:26 +02:00
commit bb9084dfed
No known key found for this signature in database
GPG key ID: 5D05538A45D5149F
13 changed files with 1934 additions and 0 deletions

9
macros/src/lib.rs Normal file
View file

@ -0,0 +1,9 @@
mod reactive;
#[proc_macro_attribute]
pub fn reactive(
attr: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
reactive::reactive(attr.into(), input.into()).into()
}

80
macros/src/reactive.rs Normal file
View file

@ -0,0 +1,80 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::punctuated::Punctuated;
fn map_fnarg(fnarg: &syn::FnArg) -> Option<TokenStream> {
match fnarg {
syn::FnArg::Receiver(_rec) => None,
syn::FnArg::Typed(pat_typed) => {
let pat = &pat_typed.pat;
let ty = match pat_typed.ty.as_ref().to_owned() {
syn::Type::Infer(_) => None,
_ => Some(pat_typed.ty.as_ref()),
};
let ty = ty.map(|t| quote! {: #t});
Some(quote! {
let #pat #ty = ::leptos_reactive_axum::extract().await.unwrap();
})
},
}
}
pub(crate) fn reactive(attr: TokenStream, input: TokenStream) -> TokenStream {
let syn::ItemFn {
attrs,
vis,
mut sig,
block,
} = match syn::parse2(input) {
Ok(input) => input,
Err(err) => return err.to_compile_error(),
};
let extract_body = match syn::parse2::<syn::LitBool>(attr) {
Ok(attr) => attr,
Err(err) => return err.to_compile_error(),
}
.value();
let prepend = quote! {
let __runtime = leptos_reactive::create_runtime();
scopeguard::defer!(__runtime.dispose());
leptos_reactive::provide_context(__parts);
};
let stmts = &block.stmts;
let mut extractors = Vec::new();
let body = if extract_body {
if let Some(fnarg) = sig.inputs.pop() {
Some(fnarg.into_value())
} else {
None
}
} else {
None
};
sig.inputs.iter().for_each(|fnarg| {
extractors.push(map_fnarg(fnarg));
});
let extractors = extractors.iter().filter(|e| e.is_some());
sig.inputs = Punctuated::new();
sig.inputs
.push(syn::parse2(quote! {__parts: ::http::request::Parts}).unwrap());
if let Some(body) = body {
sig.inputs.push(body);
}
quote! {
#(#attrs)* #vis #sig {
#prepend
#(#extractors)*
#(#stmts)*
}
}
}