From 51ceac1e2c43601fa6798da5ff2f71b21534b02c Mon Sep 17 00:00:00 2001 From: Jarek Samic Date: Fri, 19 Jun 2020 20:00:07 -0400 Subject: [PATCH] [chat] Support text hex colors in 1.16 --- protocol/src/chat.rs | 95 +++++++++++++++++++++++++++++-- protocol/test/chat/hex_color.json | 1 + 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 protocol/test/chat/hex_color.json diff --git a/protocol/src/chat.rs b/protocol/src/chat.rs index 2276673..92b9077 100644 --- a/protocol/src/chat.rs +++ b/protocol/src/chat.rs @@ -65,8 +65,7 @@ use crate::impl_json_encoder_decoder; use serde::{Deserialize, Serialize}; use serde_json::Error; -#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] +#[derive(Debug, Eq, PartialEq)] pub enum Color { Black, DarkBlue, @@ -84,6 +83,70 @@ pub enum Color { LightPurple, Yellow, White, + /// A hex color string + /// + /// Support for this was added in 1.16. + /// + /// # Examples + /// + /// ``` + /// use minecraft_protocol::chat::Color; + /// + /// let color = Color::Hex("#f98aff".into()); + /// ``` + Hex(String), +} + +impl From for Color { + fn from(val: String) -> Self { + if val.starts_with("#") { + Self::Hex(val) + } else { + match val.as_ref() { + "black" => Self::Black, + "dark_blue" => Self::DarkBlue, + "dark_green" => Self::DarkGreen, + "dark_aqua" => Self::DarkAqua, + "dark_red" => Self::DarkRed, + "dark_purple" => Self::DarkPurple, + "gold" => Self::Gold, + "gray" => Self::Gray, + "dark_gray" => Self::DarkGray, + "blue" => Self::Blue, + "green" => Self::Green, + "aqua" => Self::Aqua, + "red" => Self::Red, + "light_purple" => Self::LightPurple, + "yellow" => Self::Yellow, + "white" => Self::White, + _ => unreachable!(), + } + } + } +} + +impl ToString for Color { + fn to_string(&self) -> String { + match self { + Color::Black => "black".into(), + Color::DarkBlue => "dark_blue".into(), + Color::DarkGreen => "dark_green".into(), + Color::DarkAqua => "dark_aqua".into(), + Color::DarkRed => "dark_red".into(), + Color::DarkPurple => "dark_purple".into(), + Color::Gold => "gold".into(), + Color::Gray => "gray".into(), + Color::DarkGray => "dark_gray".into(), + Color::Blue => "blue".into(), + Color::Green => "green".into(), + Color::Aqua => "aqua".into(), + Color::Red => "red".into(), + Color::LightPurple => "light_purple".into(), + Color::Yellow => "yellow".into(), + Color::White => "white".into(), + Color::Hex(val) => { val.into() } + } + } } #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] @@ -205,7 +268,7 @@ pub struct Message { #[serde(skip_serializing_if = "Option::is_none")] pub obfuscated: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub color: Option, + pub color: Option, #[serde(skip_serializing_if = "Option::is_none")] pub insertion: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -291,7 +354,7 @@ impl MessageBuilder { } pub fn color(mut self, color: Color) -> Self { - self.current.color = Some(color); + self.current.color = Some(color.to_string()); self } @@ -631,3 +694,27 @@ fn test_deserialize_hover_show_entity() { Message::from_json(include_str!("../test/chat/hover_show_entity.json")).unwrap() ); } + +#[test] +fn test_serialize_hex_color() { + let message = MessageBuilder::builder(Payload::text("Hello")) + .color(Color::Hex("#ffffff".into())) + .build(); + + assert_eq!( + message.to_json().unwrap(), + include_str!("../test/chat/hex_color.json") + ); +} + +#[test] +fn test_deserialize_hex_color() { + let expected_message = MessageBuilder::builder(Payload::text("Hello")) + .color(Color::Hex("#ffffff".into())) + .build(); + + assert_eq!( + Message::from_json(include_str!("../test/chat/hex_color.json")).unwrap(), + expected_message + ); +} diff --git a/protocol/test/chat/hex_color.json b/protocol/test/chat/hex_color.json new file mode 100644 index 0000000..a139581 --- /dev/null +++ b/protocol/test/chat/hex_color.json @@ -0,0 +1 @@ +{"color":"#ffffff","text":"Hello"} \ No newline at end of file