From aa2638977780154359b9533c01ffbf846b9150d7 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Fri, 27 Jan 2023 00:30:13 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20[pagetop-macros]=20Macros=20para?= =?UTF-8?q?=20facilitar=20la=20vida?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagetop-macros/Cargo.toml | 23 +++++++++++++++++++ pagetop-macros/README.md | 26 ++++++++++++++++++++++ pagetop-macros/src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 pagetop-macros/Cargo.toml create mode 100644 pagetop-macros/README.md create mode 100644 pagetop-macros/src/lib.rs diff --git a/pagetop-macros/Cargo.toml b/pagetop-macros/Cargo.toml new file mode 100644 index 00000000..2aa4ec10 --- /dev/null +++ b/pagetop-macros/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "pagetop-macros" +version = "0.0.1" +edition = "2021" + +authors = [ + "Manuel Cillero " +] +description = """\ + Useful macros for creating web solutions using the PageTop framework.\ +""" +homepage = "https://pagetop.cillero.es" +repository = "https://github.com/manuelcillero/pagetop" +license = "Apache-2.0 OR MIT" + +[lib] +proc-macro = true + +[dependencies] +concat-string = "1.0.1" +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "1.0", features = ["full"] } diff --git a/pagetop-macros/README.md b/pagetop-macros/README.md new file mode 100644 index 00000000..c8d634b8 --- /dev/null +++ b/pagetop-macros/README.md @@ -0,0 +1,26 @@ +Macros útiles para la creación de soluciones web con **PageTop**. + +[PageTop](https://github.com/manuelcillero/pagetop/tree/main/pagetop), es un entorno de desarrollo +basado en algunos de los *crates* más estables y populares del ecosistema Rust para proporcionar +APIs, patrones de desarrollo y buenas prácticas para la creación de soluciones web SSR (*Server-Side +Rendering*). + + +# 🚧 Advertencia + +**PageTop** sólo libera actualmente versiones de desarrollo. La API no es estable y los cambios son +constantes. No puede considerarse preparado hasta que se libere la versión **0.1.0**. + + +# 📜 Licencia + +Este proyecto tiene licencia, de hecho tiene dos, puedes aplicar cualquiera de las siguientes a tu +elección: + +* Licencia Apache versión 2.0 + ([LICENSE-APACHE](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-APACHE) o + [http://www.apache.org/licenses/LICENSE-2.0]). + +* Licencia MIT + ([LICENSE-MIT](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-MIT) o + [http://opensource.org/licenses/MIT]). diff --git a/pagetop-macros/src/lib.rs b/pagetop-macros/src/lib.rs new file mode 100644 index 00000000..d3fa4f51 --- /dev/null +++ b/pagetop-macros/src/lib.rs @@ -0,0 +1,47 @@ +use concat_string::concat_string; +use proc_macro::TokenStream; +use quote::{quote, quote_spanned, ToTokens}; +use syn::{parse_macro_input, parse_str, ItemFn}; + +#[proc_macro_attribute] +pub fn fn_with(_attr: TokenStream, item: TokenStream) -> TokenStream { + let fn_item = parse_macro_input!(item as ItemFn); + let fn_name = fn_item.sig.ident.to_string(); + + if !fn_name.starts_with("alter_") { + let expanded = quote_spanned! { + fn_item.sig.ident.span() => + compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method"); + }; + return expanded.into(); + } + + let args: Vec = fn_item + .sig + .inputs + .iter() + .skip(1) + .map(|arg| arg.to_token_stream().to_string()) + .collect(); + + let param: Vec = args + .iter() + .map(|arg| arg.split_whitespace().next().unwrap().to_string()) + .collect(); + + #[rustfmt::skip] + let fn_builder = parse_str::(concat_string!(" + pub fn ", fn_name.replace("alter_", "with_"), "(mut self, ", args.join(", "), ") -> Self { + self.", fn_name, "(", param.join(", "), "); + self + } + ").as_str()).unwrap(); + + let fn_original = fn_item.into_token_stream(); + + let expanded = quote! { + #fn_builder + #fn_original + }; + expanded.into() +}