aboutsummaryrefslogtreecommitdiff
path: root/minecraft-chat
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-09 17:28:18 +0000
committermat <github@matdoes.dev>2021-12-09 17:28:18 +0000
commit577c2aa5444db727c23ceae565a8648d6f6a41f4 (patch)
treecc96eb8cee284cc9303def29f790aaf79e53fb4b /minecraft-chat
parent4bf2ef15f9ce6a676834721e00f01608b51c0950 (diff)
downloadazalea-drasl-577c2aa5444db727c23ceae565a8648d6f6a41f4.tar.xz
add tests for to_ansi
Diffstat (limited to 'minecraft-chat')
-rw-r--r--minecraft-chat/src/component.rs39
-rw-r--r--minecraft-chat/src/style.rs79
-rw-r--r--minecraft-chat/tests/integration_test.rs5
3 files changed, 81 insertions, 42 deletions
diff --git a/minecraft-chat/src/component.rs b/minecraft-chat/src/component.rs
index c0e4f8ac..c0f7677f 100644
--- a/minecraft-chat/src/component.rs
+++ b/minecraft-chat/src/component.rs
@@ -23,12 +23,14 @@ impl Component {
// if it's primitive, make it a text component
if !json.is_array() && !json.is_object() {
- component = Component::TextComponent(TextComponent::new(json.to_string()));
+ component = Component::TextComponent(TextComponent::new(
+ json.as_str().unwrap_or("").to_string(),
+ ));
}
// if it's an object, do things with { text } and stuff
else if json.is_object() {
if json.get("text").is_some() {
- let text = json.get("text").unwrap().to_string();
+ let text = json.get("text").unwrap().as_str().unwrap_or("").to_string();
component = Component::TextComponent(TextComponent::new(text));
} else if json.get("translate").is_some() {
let translate = json.get("translate").unwrap().to_string();
@@ -133,6 +135,11 @@ impl Component {
}
}
+ // var5_17.setStyle((Style)jsonDeserializationContext.deserialize(jsonElement, Style.class));
+ let style = Style::deserialize(json);
+ println!("set style to {:?}", style);
+ component.get_base().style = style;
+
return Ok(component);
}
// ok so it's not an object, if it's an array deserialize every item
@@ -172,34 +179,42 @@ impl Component {
pub fn to_ansi(&self, parent_style: Option<&mut Style>) -> String {
// the siblings of this component
let base;
- let mut text;
+ let component_text: String;
+ let mut styled_component = String::new();
match self {
Self::TextComponent(c) => {
base = &c.base;
- text = c.text.clone();
+ component_text = c.text.clone();
}
Self::TranslatableComponent(c) => {
base = &c.base;
- text = c.key.clone();
+ component_text = c.key.clone();
}
};
// we'll fall back to this if there's no parent style
let default_style = &mut Style::new();
- // apply the style of this component to the current style
+ // 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);
- let new_style = &base.style;
- current_style.apply(new_style);
- let ansi_text = base.style.compare_ansi(&new_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);
- text.push_str(&ansi_text);
+ styled_component.push_str(&ansi_text);
+ styled_component.push_str(&component_text);
for sibling in &base.siblings {
- text.push_str(&sibling.to_ansi(Some(current_style)));
+ styled_component.push_str(&sibling.to_ansi(Some(current_style)));
+ }
+
+ if is_base_style {
+ styled_component.push_str("\x1b[m");
}
- text.clone()
+ styled_component.clone()
}
}
diff --git a/minecraft-chat/src/style.rs b/minecraft-chat/src/style.rs
index fed5243f..e87bd999 100644
--- a/minecraft-chat/src/style.rs
+++ b/minecraft-chat/src/style.rs
@@ -2,8 +2,8 @@ use std::collections::HashMap;
use serde_json::Value;
-#[derive(Clone, PartialEq)]
-struct TextColor {
+#[derive(Clone, PartialEq, Debug)]
+pub struct TextColor {
value: u32,
name: Option<String>,
}
@@ -29,21 +29,21 @@ impl TextColor {
// private static final Map<String, TextColor> NAMED_COLORS = (Map)LEGACY_FORMAT_TO_COLOR.values().stream().collect(ImmutableMap.toImmutableMap(textColor -> textColor.name, Function.identity()));
let mut LEGACY_FORMAT_TO_COLOR = HashMap::new();
let mut NAMED_COLORS = HashMap::new();
- for i in ChatFormatting::FORMATTERS {
- if i.is_format && i != ChatFormatting::RESET {
+ for formatter in &ChatFormatting::FORMATTERS {
+ if !formatter.is_format && *formatter != ChatFormatting::RESET {
LEGACY_FORMAT_TO_COLOR.insert(
- i,
+ formatter,
TextColor {
- value: i.color.unwrap(),
- name: Some(i.name.to_string()),
+ value: formatter.color.unwrap(),
+ name: Some(formatter.name.to_string()),
},
);
}
}
- for i in LEGACY_FORMAT_TO_COLOR.values() {
- NAMED_COLORS.insert(i.name.unwrap(), i.clone());
+ for color in LEGACY_FORMAT_TO_COLOR.values() {
+ NAMED_COLORS.insert(color.name.as_ref().unwrap(), color.clone());
}
- let color = NAMED_COLORS.get(&value);
+ let color = NAMED_COLORS.get(&value.to_ascii_uppercase());
if color.is_some() {
return Ok(color.unwrap().clone());
}
@@ -55,9 +55,22 @@ impl TextColor {
}
}
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn text_color_named_colors() {
+ assert_eq!(
+ TextColor::parse("red".to_string()).unwrap().value,
+ 16733525u32
+ );
+ }
+}
+
const PREFIX_CODE: char = '\u{00a7}';
-#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
struct ChatFormatting<'a> {
name: &'a str,
code: char,
@@ -140,11 +153,11 @@ impl TextColor {
Self { value, name }
}
- fn format(&self) -> String {
+ pub fn format(&self) -> String {
format!("#{:06X}", self.value)
}
- fn to_string(&self) -> String {
+ pub fn to_string(&self) -> String {
if let Some(name) = &self.name {
name.clone()
} else {
@@ -153,7 +166,7 @@ impl TextColor {
}
}
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct Style {
// @Nullable
// final TextColor color;
@@ -177,12 +190,12 @@ pub struct Style {
// final ResourceLocation font;
// these are options instead of just bools because None is different than false in this case
- color: Option<TextColor>,
- bold: Option<bool>,
- italic: Option<bool>,
- underlined: Option<bool>,
- strikethrough: Option<bool>,
- obfuscated: Option<bool>,
+ pub color: Option<TextColor>,
+ pub bold: Option<bool>,
+ pub italic: Option<bool>,
+ pub underlined: Option<bool>,
+ pub strikethrough: Option<bool>,
+ pub obfuscated: Option<bool>,
}
impl Style {
@@ -197,7 +210,7 @@ impl Style {
}
}
- fn deserialize(json: Value) {
+ pub fn deserialize(json: &Value) -> Style {
// if (jsonElement.isJsonObject()) {
// JsonObject jsonObject = jsonElement.getAsJsonObject();
// if (jsonObject == null) {
@@ -216,18 +229,28 @@ impl Style {
// return new Style(textColor, bl, bl2, bl3, bl4, bl5, clickEvent, hoverEvent, string, resourceLocation);
// }
// return null;
- if json.is_object() {
+ return if json.is_object() {
let json_object = json.as_object().unwrap();
let bold = json_object.get("bold").and_then(|v| v.as_bool());
let italic = json_object.get("italic").and_then(|v| v.as_bool());
let underlined = json_object.get("underlined").and_then(|v| v.as_bool());
let strikethrough = json_object.get("strikethrough").and_then(|v| v.as_bool());
let obfuscated = json_object.get("obfuscated").and_then(|v| v.as_bool());
- let color = json_object
+ let color: Option<TextColor> = json_object
.get("color")
- .and_then(|v| v.as_string())
- .and_then(|v| TextColor::parse(v));
- }
+ .and_then(|v| v.as_str())
+ .and_then(|v| TextColor::parse(v.to_string()).ok());
+ Style {
+ color,
+ bold,
+ italic,
+ underlined,
+ strikethrough,
+ obfuscated,
+ }
+ } else {
+ Style::new()
+ };
}
/// Check if a style has no attributes set
@@ -270,7 +293,7 @@ impl Style {
let mut ansi_codes = String::new();
let before = if should_reset {
- ansi_codes.push_str("\x1b[0m");
+ ansi_codes.push_str("\x1b[m");
Style::new()
} else {
self.clone()
@@ -321,7 +344,7 @@ impl Style {
));
}
- return "".to_string();
+ ansi_codes
}
/// Apply another style to this one
diff --git a/minecraft-chat/tests/integration_test.rs b/minecraft-chat/tests/integration_test.rs
index 9fd9c093..0574861b 100644
--- a/minecraft-chat/tests/integration_test.rs
+++ b/minecraft-chat/tests/integration_test.rs
@@ -6,10 +6,11 @@ fn test() {
let j: Value = serde_json::from_str(
r#"{
"text": "hello",
- "color": "red"
+ "color": "red",
+ "bold": true
}"#,
)
.unwrap();
let component = Component::new(&j).unwrap();
- println!("println: {}", component.to_ansi(None));
+ assert_eq!(component.to_ansi(None), "\x1b[38;2;255;85;85mhello\x1b[m");
}