🧑💻 Añade macros para concatenar cadenas
This commit is contained in:
parent
0df5f3f1c7
commit
74e497f170
4 changed files with 172 additions and 3 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -525,6 +525,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concat-string"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7439becb5fafc780b6f4de382b1a7a3e70234afe783854a4702ee8adbb838609"
|
||||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.15.13"
|
||||
|
@ -1407,13 +1413,14 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
|||
|
||||
[[package]]
|
||||
name = "pagetop"
|
||||
version = "0.0.10"
|
||||
version = "0.0.11"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-web",
|
||||
"actix-web-static-files",
|
||||
"chrono",
|
||||
"colored",
|
||||
"concat-string",
|
||||
"config",
|
||||
"figlet-rs",
|
||||
"fluent-templates",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pagetop"
|
||||
version = "0.0.10"
|
||||
version = "0.0.11"
|
||||
edition = "2021"
|
||||
|
||||
description = """\
|
||||
|
@ -17,6 +17,7 @@ authors.workspace = true
|
|||
[dependencies]
|
||||
chrono = "0.4.41"
|
||||
colored = "3.0.0"
|
||||
concat-string = "1.0.1"
|
||||
config = { version = "0.15.13", default-features = false, features = ["toml"] }
|
||||
figlet-rs = "0.1.5"
|
||||
itoa = "1.0.15"
|
||||
|
|
|
@ -9,7 +9,7 @@ pub use crate::{AutoDefault, StaticResources};
|
|||
// MACROS.
|
||||
|
||||
// crate::util
|
||||
pub use crate::hm;
|
||||
pub use crate::{hm, join, join_opt, join_pair, join_strict};
|
||||
// crate::config
|
||||
pub use crate::include_config;
|
||||
// crate::locale
|
||||
|
|
161
src/util.rs
161
src/util.rs
|
@ -5,6 +5,7 @@ use crate::trace;
|
|||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// FUNCIONES ÚTILES ********************************************************************************
|
||||
|
||||
/// Devuelve la ruta absoluta a un directorio existente.
|
||||
///
|
||||
|
@ -51,6 +52,9 @@ where
|
|||
#[doc(hidden)]
|
||||
pub use paste::paste;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use concat_string::concat_string;
|
||||
|
||||
#[macro_export]
|
||||
/// Macro para construir una colección de pares clave-valor.
|
||||
///
|
||||
|
@ -73,3 +77,160 @@ macro_rules! hm {
|
|||
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, String::from("Hello World"));
|
||||
///
|
||||
/// // También funciona con valores vacíos.
|
||||
/// let result_with_empty = join!("Hello", "", "World");
|
||||
/// assert_eq!(result_with_empty, String::from("HelloWorld"));
|
||||
///
|
||||
/// // Un único fragmento devuelve el mismo valor.
|
||||
/// let single_result = join!("Hello");
|
||||
/// assert_eq!(single_result, String::from("Hello"));
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! join {
|
||||
($($arg:tt)*) => {
|
||||
$crate::util::concat_string!($($arg)*)
|
||||
};
|
||||
}
|
||||
|
||||
/// Concatena los fragmentos no vacíos en un [`Option<String>`] con un separador opcional.
|
||||
///
|
||||
/// Esta macro acepta cualquier número de fragmentos que implementen [`AsRef<str>`] para concatenar
|
||||
/// todos los fragmentos no vacíos usando opcionalmente un separador.
|
||||
///
|
||||
/// Si todos los fragmentos están vacíos, devuelve [`None`].
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
///
|
||||
/// // Concatena los fragmentos no vacíos con un espacio como separador.
|
||||
/// let result_with_separator = join_opt!(["Hello", "", "World"]; " ");
|
||||
/// assert_eq!(result_with_separator, Some(String::from("Hello World")));
|
||||
///
|
||||
/// // Concatena los fragmentos no vacíos sin un separador.
|
||||
/// let result_without_separator = join_opt!(["Hello", "", "World"]);
|
||||
/// assert_eq!(result_without_separator, Some(String::from("HelloWorld")));
|
||||
///
|
||||
/// // Devuelve `None` si todos los fragmentos están vacíos.
|
||||
/// let result_empty = join_opt!(["", "", ""]);
|
||||
/// assert_eq!(result_empty, None);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! join_opt {
|
||||
([$($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 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, String::from("Hello-World"));
|
||||
///
|
||||
/// // Si el primer fragmento está vacío, devuelve el segundo.
|
||||
/// let result_empty_first = join_pair!("", separator, second);
|
||||
/// assert_eq!(result_empty_first, String::from("World"));
|
||||
///
|
||||
/// // Si el segundo fragmento está vacío, devuelve el primero.
|
||||
/// let result_empty_second = join_pair!(first, separator, "");
|
||||
/// assert_eq!(result_empty_second, String::from("Hello"));
|
||||
///
|
||||
/// // Si ambos fragmentos están vacíos, devuelve una cadena vacía.
|
||||
/// let result_both_empty = join_pair!("", separator, "");
|
||||
/// assert_eq!(result_both_empty, String::from(""));
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! join_pair {
|
||||
($first:expr, $separator:expr, $second:expr) => {{
|
||||
if $first.is_empty() {
|
||||
String::from($second)
|
||||
} else if $second.is_empty() {
|
||||
String::from($first)
|
||||
} else {
|
||||
$crate::util::concat_string!($first, $separator, $second)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Concatena varios fragmentos en un [`Option<String>`] si ninguno está vacío.
|
||||
///
|
||||
/// Si alguno de los fragmentos, que deben implementar [`AsRef<str>`], está vacío, devuelve
|
||||
/// [`None`]. Opcionalmente se puede indicar un separador entre los fragmentos concatenados.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
///
|
||||
/// // Concatena los fragmentos.
|
||||
/// let result = join_strict!(["Hello", "World"]);
|
||||
/// assert_eq!(result, Some(String::from("HelloWorld")));
|
||||
///
|
||||
/// // Concatena los fragmentos con un separador.
|
||||
/// let result_with_separator = join_strict!(["Hello", "World"]; " ");
|
||||
/// assert_eq!(result_with_separator, Some(String::from("Hello World")));
|
||||
///
|
||||
/// // Devuelve `None` si alguno de los fragmentos está vacío.
|
||||
/// let result_with_empty = join_strict!(["Hello", "", "World"]);
|
||||
/// assert_eq!(result_with_empty, None);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! join_strict {
|
||||
([$($arg:expr),* $(,)?]) => {{
|
||||
let fragments = [$($arg),*];
|
||||
if fragments.iter().any(|&item| item.is_empty()) {
|
||||
None
|
||||
} else {
|
||||
Some(fragments.concat())
|
||||
}
|
||||
}};
|
||||
([$($arg:expr),* $(,)?]; $separator:expr) => {{
|
||||
let fragments = [$($arg),*];
|
||||
if fragments.iter().any(|&item| item.is_empty()) {
|
||||
None
|
||||
} else {
|
||||
Some(fragments.join($separator))
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue