1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

Implement suggested changes

This commit is contained in:
Kumpelinus 2025-04-28 15:36:33 +02:00
parent bf2bfd3bcb
commit ead5acc151
3 changed files with 77 additions and 11 deletions

View file

@ -67,6 +67,44 @@ impl FormattedText {
}
}
/// Render all components into a single `String`, using your custom
/// closures to drive styling, text transformation, and final cleanup.
///
/// # Type params
/// - `F`: `(running, component, default) -> (prefix, suffix)` for per-component styling
/// - `S`: `&str -> String` for text tweaks (escaping, mapping, etc.)
/// - `C`: `&final_running_style -> String` for any trailing cleanup
///
/// # Args
/// - `style_formatter`: how to open/close each components style
/// - `text_formatter`: how to turn raw text into output text
/// - `cleanup_formatter`: emit after all components (e.g. reset codes)
/// - `default_style`: where to reset when a components `reset` is true
///
/// # Example
/// ```rust
/// use azalea_chat::{FormattedText, DEFAULT_STYLE};
/// use serde::de::Deserialize;
///
/// let component = FormattedText::deserialize(&serde_json::json!({
/// "text": "Hello, world!",
/// "color": "red",
/// })).unwrap();
///
/// let ansi = component.to_custom_format(
/// |running, new, default| (running.compare_ansi(new, default), String::new()),
/// |text| text.to_string(),
/// |style| {
/// if !style.is_empty() {
/// "\u{1b}[m".to_string()
/// } else {
/// String::new()
/// }
/// },
/// &DEFAULT_STYLE,
/// );
/// println!("{}", ansi);
/// ```
pub fn to_custom_format<F, S, C>(
&self,
mut style_formatter: F,
@ -113,6 +151,21 @@ impl FormattedText {
output
}
/// Convert this component into an
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code).
///
/// This is the same as [`FormattedText::to_ansi`], but you can specify a
/// default [`Style`] to use.
pub fn to_ansi_with_custom_style(&self, default_style: &Style) -> String {
self.to_custom_format(
|running, new, default| (running.compare_ansi(new, default), "".to_owned()),
|text| text.to_string(),
|style| if !style.is_empty() { "\u{1b}[m" } else { "" }.to_string(),
default_style,
)
}
/// Convert this component into an
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code), so you
/// can print it to your terminal and get styling.
@ -135,23 +188,18 @@ impl FormattedText {
/// println!("{}", component.to_ansi());
/// ```
pub fn to_ansi(&self) -> String {
self.to_custom_format(
|running, new, default| (running.compare_ansi(new, default), "".to_owned()),
|text| text.to_string(),
|style| if !style.is_empty() { "\u{1b}[m" } else { "" }.to_string(),
&DEFAULT_STYLE,
)
self.to_ansi_with_custom_style(&DEFAULT_STYLE)
}
pub fn to_html(&self) -> String {
self.to_custom_format(
|_, new, _| {
|running, new, _| {
(
format!("<span style=\"{}\">", new.get_html_style()),
format!("<span style=\"{}\">", running.merged_with(new).get_html_style()),
"</span>".to_owned(),
)
},
|text| text.replace("\n", "<br>"),
|text| text.replace("<", "&lt;").replace("\n", "<br>"),
|_| "".to_string(),
&DEFAULT_STYLE,
)

View file

@ -8,4 +8,4 @@ pub mod style;
pub mod text_component;
pub mod translatable_component;
pub use component::FormattedText;
pub use component::{FormattedText, DEFAULT_STYLE};

View file

@ -146,7 +146,7 @@ mod tests {
use crate::style::Ansi;
#[test]
fn test_hypixel_motd() {
fn test_hypixel_motd_ansi() {
let component =
TextComponent::new("§aHypixel Network §c[1.8-1.18]\n§b§lHAPPY HOLIDAYS".to_string())
.get();
@ -163,6 +163,24 @@ mod tests {
);
}
#[test]
fn test_hypixel_motd_html() {
let component =
TextComponent::new("§aHypixel Network §c[1.8-1.18]\n§b§lHAPPY HOLIDAYS".to_string())
.get();
assert_eq!(
component.to_html(),
format!(
"{GREEN}Hypixel Network {END_SPAN}{RED}[1.8-1.18]<br>{END_SPAN}{BOLD_AQUA}HAPPY HOLIDAYS{END_SPAN}",
END_SPAN = "</span>",
GREEN = "<span style=\"color: #55FF55;\">",
RED = "<span style=\"color: #FF5555;\">",
BOLD_AQUA = "<span style=\"color: #55FFFF;font-weight: bold;\">",
)
);
}
#[test]
fn test_legacy_color_code_to_component() {
let component = TextComponent::new("§lHello §r§1w§2o§3r§4l§5d".to_string()).get();