🎉 [pagetop-macros] Macros para facilitar la vida

This commit is contained in:
Manuel Cillero 2023-01-27 00:30:13 +01:00
parent 065fe9eaab
commit aa26389777
3 changed files with 96 additions and 0 deletions

23
pagetop-macros/Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "pagetop-macros"
version = "0.0.1"
edition = "2021"
authors = [
"Manuel Cillero <manuel@cillero.es>"
]
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"] }

26
pagetop-macros/README.md Normal file
View file

@ -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]).

47
pagetop-macros/src/lib.rs Normal file
View file

@ -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<String> = fn_item
.sig
.inputs
.iter()
.skip(1)
.map(|arg| arg.to_token_stream().to_string())
.collect();
let param: Vec<String> = args
.iter()
.map(|arg| arg.split_whitespace().next().unwrap().to_string())
.collect();
#[rustfmt::skip]
let fn_builder = parse_str::<ItemFn>(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()
}