pagetop/src/html/join_classes.rs
Manuel Cillero 5ec69345b3 Añade trait JoinClasses para unir clases CSS
También elimina macros sin uso `join_op!` y `join_strict!` (KISS).
2025-11-08 08:07:59 +01:00

67 lines
2.3 KiB
Rust

/// Añade a los *slices* de elementos [`AsRef<str>`] un método para unir clases CSS.
///
/// El método es [`join_classes()`](JoinClasses::join_classes), que une las cadenas **no vacías**
/// del *slice* usando un espacio como separador.
pub trait JoinClasses {
/// Une las cadenas **no vacías** de un *slice* usando un espacio como separador.
///
/// Son cadenas vacías únicamente los elementos del *slice* cuya longitud es `0` (p. ej., `""`);
/// no se realiza recorte ni normalización, por lo que elementos como `" "` no se consideran
/// vacíos.
///
/// Si todas las cadenas están vacías, devuelve una cadena vacía. Acepta elementos que
/// implementen [`AsRef<str>`] como `&str`, [`String`] o `Cow<'_, str>`.
///
/// # Ejemplos
///
/// ```rust
/// # use pagetop::prelude::*;
/// let classes = ["btn", "", "btn-primary"];
/// assert_eq!(classes.join_classes(), "btn btn-primary");
///
/// let empty: [&str; 3] = ["", "", ""];
/// assert_eq!(empty.join_classes(), "");
///
/// let border = String::from("border");
/// let border_top = String::from("border-top-0");
/// let v = vec![&border, "", "", "", &border_top];
/// assert_eq!(v.as_slice().join_classes(), "border border-top-0");
///
/// // Elementos con espacios afectan al resultado.
/// let spaced = ["btn", " ", "primary "];
/// assert_eq!(spaced.join_classes(), "btn primary ");
/// ```
fn join_classes(&self) -> String;
}
impl<T> JoinClasses for [T]
where
T: AsRef<str>,
{
#[inline]
fn join_classes(&self) -> String {
let mut count = 0usize;
let mut total = 0usize;
for s in self.iter().map(T::as_ref).filter(|s| !s.is_empty()) {
count += 1;
total += s.len();
}
if count == 0 {
return String::new();
}
let separator = " ";
let mut result = String::with_capacity(total + separator.len() * count.saturating_sub(1));
for (i, s) in self
.iter()
.map(T::as_ref)
.filter(|s| !s.is_empty())
.enumerate()
{
if i > 0 {
result.push_str(separator);
}
result.push_str(s);
}
result
}
}