aboutsummaryrefslogtreecommitdiff
path: root/minecraft-chat/src/style.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-11 15:17:42 -0600
committermat <github@matdoes.dev>2021-12-11 15:17:42 -0600
commitba911a8a207eb47df7a055410570767b2e33c2ae (patch)
tree4a53d384f08b7272ba287bdb326f3d7fcb09f289 /minecraft-chat/src/style.rs
parent6026c74430f311c9217b77e7ac07d183efde5bce (diff)
downloadazalea-drasl-ba911a8a207eb47df7a055410570767b2e33c2ae.tar.xz
correct minecraft-chat :tada:
Diffstat (limited to 'minecraft-chat/src/style.rs')
-rw-r--r--minecraft-chat/src/style.rs162
1 files changed, 79 insertions, 83 deletions
diff --git a/minecraft-chat/src/style.rs b/minecraft-chat/src/style.rs
index 14fabec5..7b333e5f 100644
--- a/minecraft-chat/src/style.rs
+++ b/minecraft-chat/src/style.rs
@@ -188,29 +188,21 @@ impl TextColor {
}
}
+// from ChatFormatting to TextColor
+impl TryFrom<ChatFormatting<'_>> for TextColor {
+ type Error = String;
+
+ fn try_from(formatter: ChatFormatting<'_>) -> Result<Self, Self::Error> {
+ if formatter.is_format {
+ return Err(format!("{} is not a color", formatter.name));
+ }
+ let color = formatter.color.unwrap_or(0);
+ Ok(Self::new(color, Some(formatter.name.to_string())))
+ }
+}
+
#[derive(Clone, Debug)]
pub struct Style {
- // @Nullable
- // final TextColor color;
- // @Nullable
- // final Boolean bold;
- // @Nullable
- // final Boolean italic;
- // @Nullable
- // final Boolean underlined;
- // @Nullable
- // final Boolean strikethrough;
- // @Nullable
- // final Boolean obfuscated;
- // @Nullable
- // final ClickEvent clickEvent;
- // @Nullable
- // final HoverEvent hoverEvent;
- // @Nullable
- // final String insertion;
- // @Nullable
- // final ResourceLocation font;
-
// these are options instead of just bools because None is different than false in this case
pub color: Option<TextColor>,
pub bold: Option<bool>,
@@ -218,17 +210,24 @@ pub struct Style {
pub underlined: Option<bool>,
pub strikethrough: Option<bool>,
pub obfuscated: Option<bool>,
+ /// Whether it should reset the formatting before applying these styles
+ pub reset: bool,
}
impl Style {
- pub fn default() -> Style {
- Style {
+ pub fn default() -> Self {
+ Self::empty()
+ }
+
+ pub fn empty() -> Self {
+ Self {
color: None,
bold: None,
italic: None,
underlined: None,
strikethrough: None,
obfuscated: None,
+ reset: false,
}
}
@@ -251,6 +250,7 @@ impl Style {
underlined,
strikethrough,
obfuscated,
+ ..Style::default()
}
} else {
Style::default()
@@ -268,43 +268,36 @@ impl Style {
}
/// find the necessary ansi code to get from this style to another
- pub fn compare_ansi(&self, after: &Style) -> String {
- let should_reset = {
+ pub fn compare_ansi(&self, after: &Style, default_style: &Style) -> String {
+ let should_reset = after.reset ||
// if it used to be bold and now it's not, reset
- if self.bold.unwrap_or(false) && !after.bold.unwrap_or(true) {
- true
- }
+ (self.bold.unwrap_or(false) && !after.bold.unwrap_or(true)) ||
// if it used to be italic and now it's not, reset
- else if self.italic.unwrap_or(false) && !after.italic.unwrap_or(true) {
- true
+ (self.italic.unwrap_or(false) && !after.italic.unwrap_or(true)) ||
// if it used to be underlined and now it's not, reset
- } else if self.underlined.unwrap_or(false) && !after.underlined.unwrap_or(true) {
- true
+ (self.underlined.unwrap_or(false) && !after.underlined.unwrap_or(true)) ||
// if it used to be strikethrough and now it's not, reset
- } else if self.strikethrough.unwrap_or(false) && !after.strikethrough.unwrap_or(true) {
- true
+ (self.strikethrough.unwrap_or(false) && !after.strikethrough.unwrap_or(true)) ||
// if it used to be obfuscated and now it's not, reset
- } else {
- self.obfuscated.unwrap_or(false) && !after.obfuscated.unwrap_or(true)
- }
- };
+ (self.obfuscated.unwrap_or(false) && !after.obfuscated.unwrap_or(true));
let mut ansi_codes = String::new();
+ let empty_style = Style::empty();
+
let (before, after) = if should_reset {
- // if it's true before and none after, make it true after
- // if it's false before and none after, make it false after
- // we should apply after into before and use that as after
ansi_codes.push_str(Ansi::RESET);
- let mut updated_after = self.clone();
+ let mut updated_after = if after.reset {
+ default_style.clone()
+ } else {
+ self.clone()
+ };
updated_after.apply(after);
- (Style::default(), updated_after)
+ (&empty_style, updated_after)
} else {
- (self.clone(), after.clone())
+ (self, after.clone())
};
- println!("should_reset {:?}", should_reset);
-
// if bold used to be false/default and now it's true, set bold
if !before.bold.unwrap_or(false) && after.bold.unwrap_or(false) {
ansi_codes.push_str(Ansi::BOLD);
@@ -331,7 +324,7 @@ impl Style {
if before.color.is_none() && after.color.is_some() {
true
} else if before.color.is_some() && after.color.is_some() {
- before.color.unwrap().value != after.color.as_ref().unwrap().value
+ before.color.clone().unwrap().value != after.color.as_ref().unwrap().value
} else {
false
}
@@ -369,21 +362,14 @@ impl Style {
/// Apply a ChatFormatting to this style
pub fn apply_formatting(&mut self, formatting: &ChatFormatting) {
- match formatting {
- &ChatFormatting::BOLD => self.bold = Some(true),
- &ChatFormatting::ITALIC => self.italic = Some(true),
- &ChatFormatting::UNDERLINE => self.underlined = Some(true),
- &ChatFormatting::STRIKETHROUGH => self.strikethrough = Some(true),
- &ChatFormatting::OBFUSCATED => self.obfuscated = Some(true),
- &ChatFormatting::RESET => {
- self.color = None;
- self.bold = None;
- self.italic = None;
- self.underlined = None;
- self.strikethrough = None;
- self.obfuscated = None;
- }
- &ChatFormatting {
+ match *formatting {
+ ChatFormatting::BOLD => self.bold = Some(true),
+ ChatFormatting::ITALIC => self.italic = Some(true),
+ ChatFormatting::UNDERLINE => self.underlined = Some(true),
+ ChatFormatting::STRIKETHROUGH => self.strikethrough = Some(true),
+ ChatFormatting::OBFUSCATED => self.obfuscated = Some(true),
+ ChatFormatting::RESET => self.reset = true,
+ ChatFormatting {
name: _,
code: _,
is_format: _,
@@ -401,6 +387,8 @@ impl Style {
#[cfg(test)]
mod tests {
+ use crate::component::DEFAULT_STYLE;
+
use super::*;
#[test]
@@ -418,22 +406,15 @@ mod tests {
#[test]
fn ansi_difference_should_reset() {
let style_a = Style {
- color: None,
bold: Some(true),
italic: Some(true),
- underlined: None,
- strikethrough: None,
- obfuscated: None,
+ ..Style::default()
};
let style_b = Style {
- color: None,
bold: Some(false),
- italic: None,
- underlined: None,
- strikethrough: None,
- obfuscated: None,
+ ..Style::default()
};
- let ansi_difference = style_a.compare_ansi(&style_b);
+ let ansi_difference = style_a.compare_ansi(&style_b, &Style::default());
assert_eq!(
ansi_difference,
format!(
@@ -446,26 +427,41 @@ mod tests {
#[test]
fn ansi_difference_shouldnt_reset() {
let style_a = Style {
- color: None,
bold: Some(true),
- italic: None,
- underlined: None,
- strikethrough: None,
- obfuscated: None,
+ ..Style::default()
};
let style_b = Style {
- color: None,
- bold: None,
italic: Some(true),
- underlined: None,
- strikethrough: None,
- obfuscated: None,
+ ..Style::default()
};
- let ansi_difference = style_a.compare_ansi(&style_b);
+ let ansi_difference = style_a.compare_ansi(&style_b, &Style::default());
assert_eq!(ansi_difference, Ansi::ITALIC)
}
#[test]
+ fn ansi_difference_explicit_reset() {
+ let style_a = Style {
+ bold: Some(true),
+ ..Style::empty()
+ };
+ let style_b = Style {
+ italic: Some(true),
+ reset: true,
+ ..Style::empty()
+ };
+ let ansi_difference = style_a.compare_ansi(&style_b, &DEFAULT_STYLE);
+ assert_eq!(
+ ansi_difference,
+ format!(
+ "{reset}{italic}{white}",
+ reset = Ansi::RESET,
+ white = Ansi::rgb(ChatFormatting::WHITE.color.unwrap()),
+ italic = Ansi::ITALIC
+ )
+ )
+ }
+
+ #[test]
fn test_from_code() {
assert_eq!(
ChatFormatting::from_code('a').unwrap(),