diff options
| author | mat <github@matdoes.dev> | 2021-12-11 11:38:12 -0600 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2021-12-11 11:38:12 -0600 |
| commit | 6026c74430f311c9217b77e7ac07d183efde5bce (patch) | |
| tree | 1d20fc2794e69e4ebb56aa1e9dd43503c39a4144 /minecraft-chat/src/text_component.rs | |
| parent | 5039f9668f3512240af22ac6bb49140012885509 (diff) | |
| download | azalea-drasl-6026c74430f311c9217b77e7ac07d183efde5bce.tar.xz | |
add legacy color codes
Diffstat (limited to 'minecraft-chat/src/text_component.rs')
| -rw-r--r-- | minecraft-chat/src/text_component.rs | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/minecraft-chat/src/text_component.rs b/minecraft-chat/src/text_component.rs index 9bca1fa0..66bde690 100644 --- a/minecraft-chat/src/text_component.rs +++ b/minecraft-chat/src/text_component.rs @@ -1,4 +1,4 @@ -use crate::base_component::BaseComponent; +use crate::{base_component::BaseComponent, component::Component, style::ChatFormatting}; #[derive(Clone, Debug)] pub struct TextComponent { @@ -6,6 +6,63 @@ pub struct TextComponent { pub text: String, } +const LEGACY_FORMATTING_CODE_SYMBOL: char = '§'; + +/// Convert a legacy color code string into a Component +/// Technically in Minecraft this is done when displaying the text, but AFAIK it's the same as just doing it in TextComponent +pub fn legacy_color_code_to_component(legacy_color_code: &str) -> Component { + let mut components: Vec<TextComponent> = Vec::with_capacity(1); + // iterate over legacy_color_code, if it starts with LEGACY_COLOR_CODE_SYMBOL then read the next character and get the style from that + // otherwise, add the character to the text + + // we don't use a normal for loop since we need to be able to skip after reading the formatter code symbol + let mut i = 0; + while i < legacy_color_code.chars().count() { + if legacy_color_code.chars().nth(i).unwrap() == LEGACY_FORMATTING_CODE_SYMBOL { + let formatting_code = legacy_color_code.chars().nth(i + 1).unwrap(); + if let Ok(formatter) = ChatFormatting::from_code(formatting_code) { + if components.is_empty() || components.last().unwrap().text.is_empty() { + components.push(TextComponent::new("".to_string())); + } + println!( + "applying formatter {:?} {:?}", + components.last_mut().unwrap().base.style, + formatter + ); + components + .last_mut() + .unwrap() + .base + .style + .apply_formatting(formatter); + println!( + "applied formatter {:?}", + components.last_mut().unwrap().base.style + ); + } + i += 1; + } else { + if components.is_empty() { + components.push(TextComponent::new("".to_string())); + } + components + .last_mut() + .unwrap() + .text + .push(legacy_color_code.chars().nth(i).unwrap()); + }; + i += 1; + } + + // create the final component by using the first one as the base, and then adding the rest as siblings + let mut final_component = components.remove(0); + for component in components { + final_component.base.siblings.push(component.get()); + } + + final_component.get() +} + impl<'a> TextComponent { pub fn new(text: String) -> Self { Self { @@ -17,4 +74,22 @@ impl<'a> TextComponent { pub fn to_string(&self) -> String { self.text.clone() } + + fn get(self) -> Component { + Component::Text(self) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_legacy_color_code_to_component() { + let component = legacy_color_code_to_component("§lHello §r§1w§2o§3r§4l§5d"); + assert_eq!( + component.to_ansi(), + "\u{1b}[38;2;170;0;170mHello world\u{1b}[m" + ); + } } |
