diff options
| author | mat <github@matdoes.dev> | 2021-12-10 21:55:25 +0000 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2021-12-10 21:55:59 +0000 |
| commit | e4460661c672c5716d7145949054cf56b0f91c64 (patch) | |
| tree | 974738c060e854d818ec74dc3b8dc2b2de89ea96 | |
| parent | 0dce5f56ce8c4ec0eb3ee4eb6c09b20956242dfa (diff) | |
| download | azalea-drasl-e4460661c672c5716d7145949054cf56b0f91c64.tar.xz | |
rewrite to_ansi
| -rw-r--r-- | minecraft-chat/src/component.rs | 91 | ||||
| -rw-r--r-- | minecraft-chat/src/text_component.rs | 4 |
2 files changed, 50 insertions, 45 deletions
diff --git a/minecraft-chat/src/component.rs b/minecraft-chat/src/component.rs index 958440ba..543b73eb 100644 --- a/minecraft-chat/src/component.rs +++ b/minecraft-chat/src/component.rs @@ -136,7 +136,7 @@ impl Component { } let style = Style::deserialize(json); - component.get_base().style = style; + component.get_base_mut().style = style; return Ok(component); } @@ -153,16 +153,25 @@ impl Component { Ok(component) } - pub fn get_base(&mut self) -> &mut BaseComponent { + // TODO: is it possible to use a macro so this doesn't have to be duplicated? + + pub fn get_base_mut(&mut self) -> &mut BaseComponent { match self { Self::TextComponent(c) => &mut c.base, Self::TranslatableComponent(c) => &mut c.base, } } + pub fn get_base(&self) -> &BaseComponent { + match self { + Self::TextComponent(c) => &c.base, + Self::TranslatableComponent(c) => &c.base, + } + } + /// Add a component as a sibling of this one fn append(&mut self, sibling: Component) { - self.get_base().siblings.push(sibling); + self.get_base_mut().siblings.push(sibling); } /// Get the "separator" component from the json @@ -173,48 +182,44 @@ impl Component { Ok(None) } - /// Convert this component into an ansi string, using parent_style as the running style. - pub fn to_ansi(&self, parent_style: Option<&mut Style>) -> String { - // the siblings of this component - let base; - let component_text: String; - let mut styled_component = String::new(); - match self { - Self::TextComponent(c) => { - base = &c.base; - component_text = c.text.clone(); - } - Self::TranslatableComponent(c) => { - base = &c.base; - component_text = c.key.clone(); - } - }; - - // we'll fall back to this if there's no parent style - let default_style = &mut Style::new(); - - // if it's the base style, that means we add a style reset at the end - let is_base_style = parent_style.is_none(); - - let current_style: &mut Style = parent_style.unwrap_or(default_style); - - // the old style is current_style and the new style is the base.style - let ansi_text = current_style.compare_ansi(&base.style); - - current_style.apply(&base.style); - println!("\nset style to {:?}", current_style); - - styled_component.push_str(&ansi_text); - styled_component.push_str(&component_text); - - for sibling in &base.siblings { - styled_component.push_str(&sibling.to_ansi(Some(current_style))); - } + /// Recursively call the function for every component in this component + pub fn visit<F>(&self, f: &mut F) -> () + where + // The closure takes an `i32` and returns an `i32`. + F: FnMut(&Component) -> (), + { + f(self); + self.get_base() + .siblings + .iter() + .for_each(|s| Component::visit(s, f)); + } - if is_base_style && ansi_text.len() > 0 { - styled_component.push_str("\x1b[m"); + /// Convert this component into an ansi string, using parent_style as the running style. + pub fn to_ansi(&self, _: Option<()>) -> String { + // this contains the final string will all the ansi escape codes + let mut built_string = String::new(); + // this style will update as we visit components + let mut running_style = Style::new(); + + self.visit(&mut |component| { + let component_text = match component { + Self::TextComponent(c) => &c.text, + Self::TranslatableComponent(c) => &c.key, + }; + let component_style = &component.get_base().style; + + let ansi_text = running_style.compare_ansi(component_style); + built_string.push_str(&ansi_text); + built_string.push_str(&component_text); + + running_style.apply(&component_style); + }); + + if !running_style.is_empty() { + built_string.push_str("\x1b[m"); } - styled_component.clone() + built_string } } diff --git a/minecraft-chat/src/text_component.rs b/minecraft-chat/src/text_component.rs index bd47d671..9bca1fa0 100644 --- a/minecraft-chat/src/text_component.rs +++ b/minecraft-chat/src/text_component.rs @@ -1,4 +1,4 @@ -use crate::{base_component::BaseComponent, component::Component}; +use crate::base_component::BaseComponent; #[derive(Clone, Debug)] pub struct TextComponent { @@ -9,8 +9,8 @@ pub struct TextComponent { impl<'a> TextComponent { pub fn new(text: String) -> Self { Self { - text: text, base: BaseComponent::new(), + text, } } |
