use crate::text::color::{ARGBColor, hsv_to_rgb}; use crate::translation::{ Locale, get_translation, get_translation_text, reorder_substitutions, translation_to_pretty, }; use click::ClickEvent; use color::Color; use colored::Colorize; use core::str; use hover::HoverEvent; use serde::de::{Error, MapAccess, SeqAccess, Visitor}; use serde::{Deserialize, Deserializer, Serialize}; use std::borrow::Cow; use std::fmt::Formatter; use style::Style; pub mod click; pub mod color; pub mod hover; pub mod style; /// Represents a text component #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct TextComponent(pub TextComponentBase); impl<'de> Deserialize<'de> for TextComponent { fn deserialize>(deserializer: D) -> Result { struct TextComponentVisitor; impl<'de> Visitor<'de> for TextComponentVisitor { type Value = TextComponentBase; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { formatter.write_str("a TextComponentBase or a sequence of TextComponentBase") } fn visit_str(self, v: &str) -> Result { Ok(TextComponentBase { content: TextContent::Text { text: Cow::from(v.to_string()), }, style: Box::default(), extra: vec![], }) } fn visit_seq>(self, mut seq: A) -> Result { let mut bases = Vec::new(); while let Some(element) = seq.next_element::()? { bases.push(element.0); } Ok(TextComponentBase { content: TextContent::Text { text: "".into() }, style: Box::default(), extra: bases, }) } fn visit_map>(self, map: A) -> Result { TextComponentBase::deserialize(serde::de::value::MapAccessDeserializer::new(map)) } } deserializer .deserialize_any(TextComponentVisitor) .map(TextComponent) } } impl Serialize for TextComponent { fn serialize(&self, serializer: S) -> Result { serializer.serialize_newtype_struct("TextComponent", &self.0.clone().to_translated()) } } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "camelCase")] pub struct TextComponentBase { /// The actual text #[serde(flatten)] pub content: TextContent, #[serde(flatten)] pub style: Box