From 3b93fc641250c4d01ab7f0764b7d5faec2f8ae5b Mon Sep 17 00:00:00 2001 From: EightFactorial Date: Sat, 3 Dec 2022 17:08:05 -0800 Subject: Serialize Component (#47) * Serializing ClientboundStatusResponsePacket Enable serialization of ClientboundStatusResponsePacket * Update clientbound_status_response_packet.rs Add options previewsChat and enforcesSecureChat * Serialize Style and TextColor * Serialize BaseComponent * Serialize TextComponent * Fix Style * Serialize Component * Fix multiple formats per message, fix reset tag * Fix Style, again * Use FlatMapSerializer * Forgot italics * Count struct fields, reorganize logic * Serialize TranslatableComponent * Rewrite TextComponent Serializer * Fix using TextColor::Parse * Code Cleanup * Add default attribute, just in case * Clippy * use serde derive feature + preferred formatting choices Co-authored-by: BuildTools Co-authored-by: mat --- azalea-chat/src/style.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'azalea-chat/src/style.rs') diff --git a/azalea-chat/src/style.rs b/azalea-chat/src/style.rs index cdf8f86f..cb708982 100755 --- a/azalea-chat/src/style.rs +++ b/azalea-chat/src/style.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, fmt}; use azalea_buf::McBuf; use once_cell::sync::Lazy; +use serde::{ser::SerializeStruct, Serialize, Serializer}; use serde_json::Value; #[derive(Clone, PartialEq, Eq, Debug)] @@ -10,6 +11,19 @@ pub struct TextColor { pub name: Option, } +impl Serialize for TextColor { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if self.name.is_some() { + serializer.serialize_str(&self.name.as_ref().unwrap().to_ascii_lowercase()) + } else { + serializer.serialize_str(&self.format()) + } + } +} + impl TextColor { pub fn parse(value: String) -> Option { if value.starts_with('#') { @@ -276,17 +290,67 @@ impl TryFrom for TextColor { #[derive(Clone, Debug, Default, PartialEq)] pub struct Style { - // 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 pub color: Option, pub bold: Option, pub italic: Option, pub underlined: Option, pub strikethrough: Option, pub obfuscated: Option, - /// Whether it should reset the formatting before applying these styles + /// Whether formatting should be reset before applying these styles pub reset: bool, } +impl Serialize for Style { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let len = if self.reset { + 6 + } else { + usize::from(self.color.is_some()) + + usize::from(self.bold.is_some()) + + usize::from(self.italic.is_some()) + + usize::from(self.underlined.is_some()) + + usize::from(self.strikethrough.is_some()) + + usize::from(self.obfuscated.is_some()) + }; + let mut state = serializer.serialize_struct("Style", len)?; + if let Some(color) = &self.color { + state.serialize_field("color", color)?; + } else if self.reset { + state.serialize_field("color", "white")?; + } + if let Some(bold) = &self.bold { + state.serialize_field("bold", bold)?; + } else if self.reset { + state.serialize_field("bold", &false)?; + } + if let Some(italic) = &self.italic { + state.serialize_field("italic", italic)?; + } else if self.reset { + state.serialize_field("italic", &false)?; + } + if let Some(underlined) = &self.underlined { + state.serialize_field("underlined", underlined)?; + } else if self.reset { + state.serialize_field("underlined", &false)?; + } + if let Some(strikethrough) = &self.strikethrough { + state.serialize_field("strikethrough", strikethrough)?; + } else if self.reset { + state.serialize_field("strikethrough", &false)?; + } + if let Some(obfuscated) = &self.obfuscated { + state.serialize_field("obfuscated", obfuscated)?; + } else if self.reset { + state.serialize_field("obfuscated", &false)?; + } + state.end() + } +} + impl Style { pub fn empty() -> Self { Self::default() -- cgit v1.2.3