161 lines
6.2 KiB
Rust
161 lines
6.2 KiB
Rust
/*!
|
|
<div align="center">
|
|
|
|
<h1>PageTop Minimal</h1>
|
|
|
|
<p>Reúne un conjunto mínimo de macros para mejorar el formato y la eficiencia de operaciones básicas en <strong>PageTop</strong>.</p>
|
|
|
|
[](https://docs.rs/pagetop-minimal)
|
|
[](https://crates.io/crates/pagetop-minimal)
|
|
[](https://crates.io/crates/pagetop-minimal)
|
|
[](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-minimal#licencia)
|
|
|
|
</div>
|
|
|
|
## 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.
|
|
|
|
## Descripción general
|
|
|
|
Este *crate* proporciona un conjunto básico de macros que se integran en las utilidades de PageTop
|
|
para optimizar operaciones habituales relacionadas con la composición estructurada de texto, la
|
|
concatenación de cadenas y el uso rápido de colecciones clave-valor.
|
|
|
|
## Créditos
|
|
|
|
Las macros para texto multilínea **`indoc!`**, **`formatdoc!`** y **`concatdoc!`** se reexportan del
|
|
*crate* [indoc](https://crates.io/crates/indoc) de [David Tolnay](https://crates.io/users/dtolnay).
|
|
|
|
Las macros para la concatenación de cadenas **`join!`** y **`join_pair!`** se apoyan internamente en
|
|
el *crate* [concat-string](https://crates.io/crates/concat_string), desarrollado por
|
|
[FaultyRAM](https://crates.io/users/FaultyRAM), para evitar el formato de cadenas cuando la
|
|
eficiencia pueda ser relevante.
|
|
|
|
La macro para generar identificadores dinámicos **`paste!`** se reexporta del *crate*
|
|
[pastey](https://crates.io/crates/pastey), una implementación avanzada y soportada del popular
|
|
`paste!` de [David Tolnay](https://crates.io/users/dtolnay).
|
|
*/
|
|
|
|
#![doc(
|
|
html_favicon_url = "https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/static/favicon.ico"
|
|
)]
|
|
|
|
#[doc(hidden)]
|
|
pub use concat_string::concat_string;
|
|
|
|
pub use indoc::{concatdoc, formatdoc, indoc};
|
|
|
|
/// Permite *pegar* tokens y generar identificadores a partir de otros.
|
|
///
|
|
/// Dentro de `paste!`, los identificadores escritos como `[< ... >]` se combinan en uno solo que
|
|
/// puede reutilizarse para referirse a items existentes o para definir nuevos (funciones,
|
|
/// estructuras, métodos, etc.).
|
|
///
|
|
/// También admite modificadores de estilo (`lower`, `upper`, `snake`, `camel`, etc.) para
|
|
/// transformar fragmentos interpolados antes de construir el nuevo identificador.
|
|
pub use pastey::paste;
|
|
// La documentación anterior se copia en `pagetop::util::paste!` porque el *crate* original no la
|
|
// define y `pagetop` no la hereda automáticamente.
|
|
|
|
/// Concatena eficientemente varios fragmentos en un [`String`].
|
|
///
|
|
/// Esta macro exporta [`concat_string!`](https://docs.rs/concat-string). Acepta cualquier número de
|
|
/// fragmentos que implementen [`AsRef<str>`] y construye un [`String`] con el tamaño óptimo, de
|
|
/// forma eficiente y evitando el uso de cadenas de formato que penalicen el rendimiento.
|
|
///
|
|
/// # Ejemplo
|
|
///
|
|
/// ```rust
|
|
/// # use pagetop_minimal::join;
|
|
/// // Concatena todos los fragmentos directamente.
|
|
/// let result = join!("Hello", " ", "World");
|
|
/// assert_eq!(result, "Hello World".to_string());
|
|
///
|
|
/// // También funciona con valores vacíos.
|
|
/// let result_with_empty = join!("Hello", "", "World");
|
|
/// assert_eq!(result_with_empty, "HelloWorld".to_string());
|
|
///
|
|
/// // Un único fragmento devuelve el mismo valor.
|
|
/// let single_result = join!("Hello");
|
|
/// assert_eq!(single_result, "Hello".to_string());
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! join {
|
|
($($arg:expr),+) => {
|
|
$crate::concat_string!($($arg),+)
|
|
};
|
|
}
|
|
|
|
/// Concatena dos fragmentos en un [`String`] usando un separador inteligente.
|
|
///
|
|
/// Une los dos fragmentos, que deben implementar [`AsRef<str>`], usando el separador proporcionado.
|
|
/// Si uno de ellos está vacío, devuelve directamente el otro; y si ambos están vacíos devuelve un
|
|
/// [`String`] vacío.
|
|
///
|
|
/// # Ejemplo
|
|
///
|
|
/// ```rust
|
|
/// # use pagetop_minimal::join_pair;
|
|
/// let first = "Hello";
|
|
/// let separator = "-";
|
|
/// let second = "World";
|
|
///
|
|
/// // Concatena los dos fragmentos cuando ambos no están vacíos.
|
|
/// let result = join_pair!(first, separator, second);
|
|
/// assert_eq!(result, "Hello-World".to_string());
|
|
///
|
|
/// // Si el primer fragmento está vacío, devuelve el segundo.
|
|
/// let result_empty_first = join_pair!("", separator, second);
|
|
/// assert_eq!(result_empty_first, "World".to_string());
|
|
///
|
|
/// // Si el segundo fragmento está vacío, devuelve el primero.
|
|
/// let result_empty_second = join_pair!(first, separator, "");
|
|
/// assert_eq!(result_empty_second, "Hello".to_string());
|
|
///
|
|
/// // Si ambos fragmentos están vacíos, devuelve una cadena vacía.
|
|
/// let result_both_empty = join_pair!("", separator, "");
|
|
/// assert_eq!(result_both_empty, "".to_string());
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! join_pair {
|
|
($first:expr, $separator:expr, $second:expr) => {{
|
|
let first_val = $first;
|
|
let second_val = $second;
|
|
let separator_val = $separator;
|
|
|
|
let first = AsRef::<str>::as_ref(&first_val);
|
|
let second = AsRef::<str>::as_ref(&second_val);
|
|
let separator = if first.is_empty() || second.is_empty() {
|
|
""
|
|
} else {
|
|
AsRef::<str>::as_ref(&separator_val)
|
|
};
|
|
|
|
$crate::concat_string!(first, separator, second)
|
|
}};
|
|
}
|
|
|
|
/// Macro para construir una colección de pares clave-valor.
|
|
///
|
|
/// ```rust
|
|
/// # use pagetop_minimal::kv;
|
|
/// # use std::collections::HashMap;
|
|
/// let args:HashMap<&str, String> = kv![
|
|
/// "userName" => "Roberto",
|
|
/// "photoCount" => "3",
|
|
/// "userGender" => "male",
|
|
/// ];
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! kv {
|
|
( $($key:expr => $value:expr),* $(,)? ) => {{
|
|
let mut a = std::collections::HashMap::new();
|
|
$(
|
|
a.insert($key.into(), $value.into());
|
|
)*
|
|
a
|
|
}};
|
|
}
|