mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
add tests for to_ansi
This commit is contained in:
parent
4bf2ef15f9
commit
577c2aa544
3 changed files with 81 additions and 42 deletions
|
@ -23,12 +23,14 @@ impl Component {
|
||||||
|
|
||||||
// if it's primitive, make it a text component
|
// if it's primitive, make it a text component
|
||||||
if !json.is_array() && !json.is_object() {
|
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
|
// if it's an object, do things with { text } and stuff
|
||||||
else if json.is_object() {
|
else if json.is_object() {
|
||||||
if json.get("text").is_some() {
|
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));
|
component = Component::TextComponent(TextComponent::new(text));
|
||||||
} else if json.get("translate").is_some() {
|
} else if json.get("translate").is_some() {
|
||||||
let translate = json.get("translate").unwrap().to_string();
|
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);
|
return Ok(component);
|
||||||
}
|
}
|
||||||
// ok so it's not an object, if it's an array deserialize every item
|
// 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 {
|
pub fn to_ansi(&self, parent_style: Option<&mut Style>) -> String {
|
||||||
// the siblings of this component
|
// the siblings of this component
|
||||||
let base;
|
let base;
|
||||||
let mut text;
|
let component_text: String;
|
||||||
|
let mut styled_component = String::new();
|
||||||
match self {
|
match self {
|
||||||
Self::TextComponent(c) => {
|
Self::TextComponent(c) => {
|
||||||
base = &c.base;
|
base = &c.base;
|
||||||
text = c.text.clone();
|
component_text = c.text.clone();
|
||||||
}
|
}
|
||||||
Self::TranslatableComponent(c) => {
|
Self::TranslatableComponent(c) => {
|
||||||
base = &c.base;
|
base = &c.base;
|
||||||
text = c.key.clone();
|
component_text = c.key.clone();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// we'll fall back to this if there's no parent style
|
// we'll fall back to this if there's no parent style
|
||||||
let default_style = &mut Style::new();
|
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 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 {
|
for sibling in &base.siblings {
|
||||||
text.push_str(&sibling.to_ansi(Some(current_style)));
|
styled_component.push_str(&sibling.to_ansi(Some(current_style)));
|
||||||
}
|
}
|
||||||
|
|
||||||
text.clone()
|
if is_base_style {
|
||||||
|
styled_component.push_str("\x1b[m");
|
||||||
|
}
|
||||||
|
|
||||||
|
styled_component.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
struct TextColor {
|
pub struct TextColor {
|
||||||
value: u32,
|
value: u32,
|
||||||
name: Option<String>,
|
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()));
|
// 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 LEGACY_FORMAT_TO_COLOR = HashMap::new();
|
||||||
let mut NAMED_COLORS = HashMap::new();
|
let mut NAMED_COLORS = HashMap::new();
|
||||||
for i in ChatFormatting::FORMATTERS {
|
for formatter in &ChatFormatting::FORMATTERS {
|
||||||
if i.is_format && i != ChatFormatting::RESET {
|
if !formatter.is_format && *formatter != ChatFormatting::RESET {
|
||||||
LEGACY_FORMAT_TO_COLOR.insert(
|
LEGACY_FORMAT_TO_COLOR.insert(
|
||||||
i,
|
formatter,
|
||||||
TextColor {
|
TextColor {
|
||||||
value: i.color.unwrap(),
|
value: formatter.color.unwrap(),
|
||||||
name: Some(i.name.to_string()),
|
name: Some(formatter.name.to_string()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i in LEGACY_FORMAT_TO_COLOR.values() {
|
for color in LEGACY_FORMAT_TO_COLOR.values() {
|
||||||
NAMED_COLORS.insert(i.name.unwrap(), i.clone());
|
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() {
|
if color.is_some() {
|
||||||
return Ok(color.unwrap().clone());
|
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}';
|
const PREFIX_CODE: char = '\u{00a7}';
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
struct ChatFormatting<'a> {
|
struct ChatFormatting<'a> {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
code: char,
|
code: char,
|
||||||
|
@ -140,11 +153,11 @@ impl TextColor {
|
||||||
Self { value, name }
|
Self { value, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format(&self) -> String {
|
pub fn format(&self) -> String {
|
||||||
format!("#{:06X}", self.value)
|
format!("#{:06X}", self.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
if let Some(name) = &self.name {
|
if let Some(name) = &self.name {
|
||||||
name.clone()
|
name.clone()
|
||||||
} else {
|
} else {
|
||||||
|
@ -153,7 +166,7 @@ impl TextColor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Style {
|
pub struct Style {
|
||||||
// @Nullable
|
// @Nullable
|
||||||
// final TextColor color;
|
// final TextColor color;
|
||||||
|
@ -177,12 +190,12 @@ pub struct Style {
|
||||||
// final ResourceLocation font;
|
// final ResourceLocation font;
|
||||||
|
|
||||||
// these are options instead of just bools because None is different than false in this case
|
// these are options instead of just bools because None is different than false in this case
|
||||||
color: Option<TextColor>,
|
pub color: Option<TextColor>,
|
||||||
bold: Option<bool>,
|
pub bold: Option<bool>,
|
||||||
italic: Option<bool>,
|
pub italic: Option<bool>,
|
||||||
underlined: Option<bool>,
|
pub underlined: Option<bool>,
|
||||||
strikethrough: Option<bool>,
|
pub strikethrough: Option<bool>,
|
||||||
obfuscated: Option<bool>,
|
pub obfuscated: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Style {
|
impl Style {
|
||||||
|
@ -197,7 +210,7 @@ impl Style {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(json: Value) {
|
pub fn deserialize(json: &Value) -> Style {
|
||||||
// if (jsonElement.isJsonObject()) {
|
// if (jsonElement.isJsonObject()) {
|
||||||
// JsonObject jsonObject = jsonElement.getAsJsonObject();
|
// JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||||
// if (jsonObject == null) {
|
// if (jsonObject == null) {
|
||||||
|
@ -216,18 +229,28 @@ impl Style {
|
||||||
// return new Style(textColor, bl, bl2, bl3, bl4, bl5, clickEvent, hoverEvent, string, resourceLocation);
|
// return new Style(textColor, bl, bl2, bl3, bl4, bl5, clickEvent, hoverEvent, string, resourceLocation);
|
||||||
// }
|
// }
|
||||||
// return null;
|
// return null;
|
||||||
if json.is_object() {
|
return if json.is_object() {
|
||||||
let json_object = json.as_object().unwrap();
|
let json_object = json.as_object().unwrap();
|
||||||
let bold = json_object.get("bold").and_then(|v| v.as_bool());
|
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 italic = json_object.get("italic").and_then(|v| v.as_bool());
|
||||||
let underlined = json_object.get("underlined").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 strikethrough = json_object.get("strikethrough").and_then(|v| v.as_bool());
|
||||||
let obfuscated = json_object.get("obfuscated").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")
|
.get("color")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_str())
|
||||||
.and_then(|v| TextColor::parse(v));
|
.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
|
/// Check if a style has no attributes set
|
||||||
|
@ -270,7 +293,7 @@ impl Style {
|
||||||
let mut ansi_codes = String::new();
|
let mut ansi_codes = String::new();
|
||||||
|
|
||||||
let before = if should_reset {
|
let before = if should_reset {
|
||||||
ansi_codes.push_str("\x1b[0m");
|
ansi_codes.push_str("\x1b[m");
|
||||||
Style::new()
|
Style::new()
|
||||||
} else {
|
} else {
|
||||||
self.clone()
|
self.clone()
|
||||||
|
@ -321,7 +344,7 @@ impl Style {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return "".to_string();
|
ansi_codes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply another style to this one
|
/// Apply another style to this one
|
||||||
|
|
|
@ -6,10 +6,11 @@ fn test() {
|
||||||
let j: Value = serde_json::from_str(
|
let j: Value = serde_json::from_str(
|
||||||
r#"{
|
r#"{
|
||||||
"text": "hello",
|
"text": "hello",
|
||||||
"color": "red"
|
"color": "red",
|
||||||
|
"bold": true
|
||||||
}"#,
|
}"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let component = Component::new(&j).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");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue