(minimal): Añade macros declarativas a utilidades

- Incorpora nuevo *crate* `pagetop-minimal` con macros básicas para
  operaciones con cadenas, bloques de texto o colecciones clave-valor.
- Refactoriza código para usar `util::join!` y `util::join_pair!` en la
  concatenación de cadenas.
- Normaliza la gestión de localización usando `util::kv!` para los
  argumentos con pares clave-valor.
- Actualizada documentación y archivos README para reflejar la nueva
  estructura y funcionalidades.
This commit is contained in:
Manuel Cillero 2025-12-07 11:55:26 +01:00
parent 0351000487
commit 6c024da51e
25 changed files with 504 additions and 154 deletions

View file

@ -8,116 +8,7 @@ use std::path::{Path, PathBuf};
// **< MACROS INTEGRADAS >**************************************************************************
#[doc(hidden)]
pub use paste::paste;
#[doc(hidden)]
pub use concat_string::concat_string;
pub use indoc::{concatdoc, formatdoc, indoc};
// **< MACROS ÚTILES >******************************************************************************
/// Macro para construir una colección de pares clave-valor.
///
/// ```rust
/// use pagetop::hm;
/// use std::collections::HashMap;
///
/// let args:HashMap<&str, String> = hm![
/// "userName" => "Roberto",
/// "photoCount" => "3",
/// "userGender" => "male",
/// ];
/// ```
#[macro_export]
macro_rules! hm {
( $($key:expr => $value:expr),* $(,)? ) => {{
let mut a = std::collections::HashMap::new();
$(
a.insert($key.into(), $value.into());
)*
a
}};
}
/// 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::prelude::*;
/// // 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::util::concat_string!($($arg),+)
};
}
/// Concatena dos fragmentos en un [`String`] usando un separador.
///
/// 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::prelude::*;
/// 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::util::concat_string!(first, separator, second)
}};
}
pub use pagetop_minimal::{concatdoc, formatdoc, indoc, join, join_pair, kv};
// **< FUNCIONES ÚTILES >***************************************************************************