use serde::{Deserialize, Serialize}; use crate::{Either, identifier::Identifier, registry::item::component_map::ItemComponentMap}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct TextComponent { // Content #[serde(flatten)] pub content: TextComponentContent, // Children pub extra: Option>, // Formatting #[serde(flatten)] pub style: TextComponentStyle, // Interactivity pub insertion: Option, pub click_event: Option, pub hover_event: Option, } impl TextComponent { // This is not the same function #[allow(clippy::should_implement_trait)] pub fn from_str(str: &str) -> Self { TextComponent { content: TextComponentContent::Text(TextComponentText { text: str.to_string(), }), extra: None, style: Default::default(), insertion: None, click_event: None, hover_event: None, } } } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Default)] pub struct TextComponentStyle { pub color: Option, pub font: Option, pub bold: Option, pub italic: Option, pub underlined: Option, pub strikethrough: Option, pub obfuscated: Option, } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] #[serde(tag = "action", content = "value", rename_all = "snake_case")] pub enum ClickEvent { OpenUrl(String), OpenFile(String), RunCommand(String), SuggestCommand(String), ChangePage(String), CopyToClipboard(String), } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "action", content = "contents", rename_all = "snake_case")] pub enum HoverEvent { ShowText(Box), ShowItem { id: Identifier, count: Option, #[serde(default)] components: ItemComponentMap, }, ShowEntity { // NOTE: Not sure if this is a TextComponent or just a string. name: String, #[serde(rename = "type")] ty: Identifier, id: Either, }, } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(untagged)] pub enum TextComponentContent { Text(TextComponentText), Translatable(TextComponentTranslatable), Score(TextComponentScore), Selector(TextComponentSelector), Keybind(TextComponentKeybind), Nbt(TextComponentNbt), } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] #[serde(tag = "type", rename = "text")] pub struct TextComponentText { pub text: String, } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "type", rename = "translatable")] pub struct TextComponentTranslatable { pub translate: String, pub fallback: Option, pub with: Option>, } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] #[serde(tag = "type", rename = "score")] pub struct TextComponentScore { pub score: TextComponentScoreInner, } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] pub struct TextComponentScoreInner { pub name: String, pub objective: String, } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "type", rename = "selector")] pub struct TextComponentSelector { pub selector: String, // TODO: Instead of an option, make this default to the default value. pub separator: Option>, } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] #[serde(tag = "type", rename = "keybind")] pub struct TextComponentKeybind { pub keybind: String, // TODO: Maybe restrict this to the allowed keybinds, or maybe leave that // for the client. } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "type", rename = "nbt")] pub struct TextComponentNbt { pub source: String, pub nbt: String, #[serde(default)] pub interpret: bool, // TODO: Instead of an option, make this default to the default value. pub separator: Option>, pub block: Option, pub entity: Option, pub storage: Option, }