[pagetop] Nuevas macros ...string! y hm! por kv!

This commit is contained in:
Manuel Cillero 2024-12-30 00:53:16 +01:00
parent 0a6d343db8
commit 4db4d791a5
5 changed files with 120 additions and 21 deletions

View file

@ -122,7 +122,7 @@ pub enum HljsLang {
static HLJS_LANGS: LazyLock<HashMap<HljsLang, &'static str>> = LazyLock::new(|| {
use HljsLang::*;
kv![
hm![
// Common languages.
Bash => "bash",
C => "c",

View file

@ -121,7 +121,7 @@ pub enum HljsTheme {
static HLJS_THEMES: LazyLock<HashMap<HljsTheme, &'static str>> = LazyLock::new(|| {
use HljsTheme::*;
kv![
hm![
A11yDark => "a11y-dark",
A11yLight => "a11y-light",
Agate => "agate",

View file

@ -85,7 +85,7 @@
//! ```
use crate::html::{Markup, PreEscaped};
use crate::{global, kv, AutoDefault};
use crate::{global, hm, AutoDefault};
pub use fluent_templates;
pub use unic_langid::{CharacterDirection, LanguageIdentifier};
@ -103,7 +103,7 @@ use std::fmt;
/// A mapping between language codes (e.g., "en-US") and their corresponding [`LanguageIdentifier`]
/// and locale key names.
static LANGUAGES: LazyLock<HashMap<String, (LanguageIdentifier, &str)>> = LazyLock::new(|| {
kv![
hm![
"en" => ( langid!("en-US"), "english" ),
"en-GB" => ( langid!("en-GB"), "english_british" ),
"en-US" => ( langid!("en-US"), "english_united_states" ),

View file

@ -9,7 +9,7 @@ pub use crate::{AutoDefault, ComponentClasses, StaticResources, UniqueId, Weight
// MACROS.
// crate::util
pub use crate::{join_string, kv};
pub use crate::{hm, join_string, option_string, trio_string};
// crate::config
pub use crate::include_config;
// crate::locale

View file

@ -146,30 +146,17 @@ pub use paste::paste;
#[doc(hidden)]
pub use concat_string::concat_string;
/// Concatena varios fragmentos de cadenas en una cadena *String*.
///
/// Exporta la macro [`concat_string!`](https://docs.rs/concat-string), que permite concatenar de
/// forma eficiente fragmentos de cadenas (*string slices*) en una cadena *String*. Acepta cualquier
/// número de argumentos que implementen `AsRef<str>` y crea una cadena `String` con el tamaño
/// adecuado, sin requerir cadenas de formato que puedan sobrecargar el rendimiento.
#[macro_export]
macro_rules! join_string {
($($arg:tt)*) => {
$crate::util::concat_string!($($arg)*)
};
}
#[macro_export]
/// Macro para construir grupos de pares clave-valor.
/// Macro para construir una colección de pares clave-valor.
///
/// ```rust#ignore
/// let args = kv![
/// let args = hm![
/// "userName" => "Roberto",
/// "photoCount" => 3,
/// "userGender" => "male",
/// ];
/// ```
macro_rules! kv {
macro_rules! hm {
( $($key:expr => $value:expr),* $(,)? ) => {{
let mut a = std::collections::HashMap::new();
$(
@ -178,3 +165,115 @@ macro_rules! kv {
a
}};
}
/// Concatena varios fragmentos de cadenas (*string slices*) en una cadena *String*.
///
/// Exporta la macro [`concat_string!`](https://docs.rs/concat-string), que permite concatenar de
/// forma eficiente fragmentos de cadenas en una cadena *String*. Acepta cualquier número de
/// argumentos que implementen `AsRef<str>` y crea una cadena `String` con el tamaño adecuado, sin
/// requerir cadenas de formato que puedan sobrecargar el rendimiento.
///
/// # Ejemplo
///
/// ```
/// // Concatena todos los fragmentos directamente.
/// let result = join_string!("Hello", " ", "World");
/// assert_eq!(result, "Hello World".to_string());
///
/// // También funciona con valores vacíos.
/// let result_with_empty = join_string!("Hello", "", "World");
/// assert_eq!(result_with_empty, "HelloWorld".to_string());
///
/// // Un único fragmento devuelve el mismo valor.
/// let single_result = join_string!("Hello");
/// assert_eq!(single_result, "Hello".to_string());
/// ```
#[macro_export]
macro_rules! join_string {
($($arg:tt)*) => {
$crate::util::concat_string!($($arg)*)
};
}
/// Concatena varios fragmentos de cadenas (*string slices*) en una cadena *String* utilizando
/// opcionalmente un separador.
///
/// Crea una cadena que contiene los fragmentos no vacíos concatenados. La macro puede utilizar un
/// separador explícito o concatenar directamente los fragmentos sin un separador. Acepta cualquier
/// número de argumentos que implementen `AsRef<str>`.
///
/// Si todos los fragmentos son cadenas vacías, devuelve `None`.
///
/// # Ejemplo
///
/// ```
/// // Concatena los fragmentos no vacíos con un espacio como separador.
/// let result_with_separator = option_string!(["Hello", "", "World"]; " ");
/// assert_eq!(result_with_separator, Some("Hello World".to_string()));
///
/// // Concatena los fragmentos no vacíos sin un separador.
/// let result_without_separator = option_string!(["Hello", "", "World"]);
/// assert_eq!(result_without_separator, Some("HelloWorld".to_string()));
///
/// // Devuelve `None` si todos los fragmentos están vacíos.
/// let result_empty = option_string!(["", "", ""]);
/// assert_eq!(result_empty, None);
/// ```
#[macro_export]
macro_rules! option_string {
([$($arg:expr),* $(,)?]) => {{
let s = $crate::util::concat_string!($($arg),*);
(!s.is_empty()).then_some(s)
}};
([$($arg:expr),* $(,)?]; $separator:expr) => {{
let s = [$($arg),*]
.iter()
.filter(|&item| !item.is_empty())
.cloned()
.collect::<Vec<_>>()
.join($separator);
(!s.is_empty()).then_some(s)
}};
}
/// Concatena dos fragmentos de cadenas (*string slices*) en una cadena *String* con un separador.
///
/// Concatena los dos fragmentos que implementen `AsRef<str>` usando el separador proporcionado,
/// pero devuelve directamente el primer fragmento si el segundo está vacío, o el segundo fragmento
/// si el primero está vacío.
///
/// # Ejemplo
///
/// ```
/// let first = "Hello";
/// let separator = "-";
/// let second = "World";
///
/// // Concatena los dos fragmentos cuando ambos no están vacíos.
/// let result = trio_string!(first, separator, second);
/// assert_eq!(result, "Hello-World".to_string());
///
/// // Si el primer fragmento está vacío, devuelve el segundo.
/// let result_empty_first = trio_string!("", separator, second);
/// assert_eq!(result_empty_first, "World".to_string());
///
/// // Si el segundo fragmento está vacío, devuelve el primero.
/// let result_empty_second = trio_string!(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 = trio_string!("", separator, "");
/// assert_eq!(result_both_empty, "".to_string());
/// ```
#[macro_export]
macro_rules! trio_string {
($first:expr, $separator:expr, $second:expr) => {{
if $first.is_empty() {
$second.to_string()
} else if $second.is_empty() {
$first.to_string()
} else {
$crate::util::concat_string!($first, $separator, $second)
}
}};
}