aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-10 21:55:25 +0000
committermat <github@matdoes.dev>2021-12-10 21:55:59 +0000
commite4460661c672c5716d7145949054cf56b0f91c64 (patch)
tree974738c060e854d818ec74dc3b8dc2b2de89ea96
parent0dce5f56ce8c4ec0eb3ee4eb6c09b20956242dfa (diff)
downloadazalea-drasl-e4460661c672c5716d7145949054cf56b0f91c64.tar.xz
rewrite to_ansi
-rw-r--r--minecraft-chat/src/component.rs91
-rw-r--r--minecraft-chat/src/text_component.rs4
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,
}
}