//!
//!
PageTop Macros
//!
//!
Una colección de macros que mejoran la experiencia de desarrollo con PageTop.
//!
//! [](#-license)
//! [](https://docs.rs/pagetop-macros)
//! [](https://crates.io/crates/pagetop-macros)
//! [](https://crates.io/crates/pagetop-macros)
//!
//!
//!
//! # 📌 Sobre PageTop
//!
//! [PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la
//! web clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles
//! y configurables, basadas en HTML, CSS y JavaScript.
mod maud;
mod smart_default;
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
use quote::{quote, quote_spanned, ToTokens};
use syn::{parse_macro_input, parse_str, DeriveInput, ItemFn};
/// Macro (*attribute*) que asocia a un método `alter_` su correspondiente método `with_` para
/// aplicar el patrón *builder*.
///
/// # Panics
///
/// Esta función provocará un *panic* si no encuentra identificadores en la lista de argumentos.
///
/// # Ejemplos
///
/// ```rust#ignore
/// #[fn_builder]
/// pub fn alter_example(&mut self) -> &mut Self {
/// // implementación
/// }
/// ```
///
/// Añadirá al código el siguiente método:
///
/// ```rust#ignore
/// #[inline]
/// pub fn with_example(mut self) -> Self {
/// self.alter_example();
/// self
/// }
/// ```
#[proc_macro_attribute]
pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
let fn_alter = parse_macro_input!(item as ItemFn);
let fn_alter_name = fn_alter.sig.ident.to_string();
if !fn_alter_name.starts_with("alter_") {
let expanded = quote_spanned! {
fn_alter.sig.ident.span() =>
compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method");
};
return expanded.into();
}
let fn_with_name = fn_alter_name.replace("alter_", "with_");
let fn_with_generics = if fn_alter.sig.generics.params.is_empty() {
fn_with_name.clone()
} else {
let g = &fn_alter.sig.generics;
format!("{fn_with_name}{}", quote! { #g }.to_string())
};
let where_clause = fn_alter
.sig
.generics
.where_clause
.as_ref()
.map_or(String::new(), |where_clause| {
format!("{} ", quote! { #where_clause }.to_string())
});
let args: Vec