online Minecraft written book viewer

feat(text): finish component subtypes

kokirigla.de abfac3f1 02ff7447

verified
+118 -3
+3 -2
justfile
··· 14 14 15 15 lint: 16 16 @cargo clippy 17 - 17 + 18 18 alias b := build 19 19 20 20 build: ··· 23 23 test: 24 24 @cargo test 25 25 26 - ok: lint test 26 + ok: lint test 27 + @cargo check --workspace
+84 -1
nara_text/src/lib.rs
··· 1 1 use serde::{Deserialize, Serialize}; 2 2 3 3 pub mod color; 4 + pub mod profile; 4 5 5 6 #[derive(Debug, Serialize, Deserialize)] 6 7 #[serde(untagged)] ··· 17 18 text: Option<TextComponent>, 18 19 #[serde(flatten)] 19 20 translation: Option<TranslationComponent>, 21 + // DO NOT FLATTEN THE SCORE COMPONENT 22 + score: Option<ScoreComponent>, 23 + #[serde(flatten)] 24 + selector: Option<SelectorComponent>, 25 + #[serde(flatten)] 26 + keybind: Option<KeybindComponent>, 27 + #[serde(flatten)] 28 + nbt: Option<NbtComponent>, 29 + #[serde(flatten)] 30 + object: Option<ObjectComponent>, 20 31 #[serde(flatten)] 21 32 formatting: ComponentFormatting, 22 33 #[serde(default, rename = "extra", skip_serializing_if = "Vec::is_empty")] 23 34 children: Vec<Component>, 24 35 } 25 36 37 + // TODO(kokiriglade): make this a struct later 38 + pub type Identifier = String; 39 + 26 40 #[serde_with::skip_serializing_none] 27 41 #[derive(Debug, Serialize, Deserialize)] 28 42 pub struct ComponentFormatting { 29 43 color: Option<color::Color>, 30 - font: Option<String>, // todo(kokiriglade): an Identifier struct? or is that too over-enginereed? 44 + font: Option<Identifier>, 31 45 bold: Option<bool>, 32 46 italic: Option<bool>, 33 47 underlined: Option<bool>, ··· 48 62 #[serde(default, skip_serializing_if = "Vec::is_empty")] 49 63 with: Vec<Component>, 50 64 } 65 + 66 + #[serde_with::skip_serializing_none] 67 + #[derive(Debug, Serialize, Deserialize)] 68 + pub struct ScoreComponent { 69 + name: String, 70 + objective: String, 71 + } 72 + 73 + #[serde_with::skip_serializing_none] 74 + #[derive(Debug, Serialize, Deserialize)] 75 + pub struct SelectorComponent { 76 + selector: String, 77 + separator: Option<Box<Component>>, 78 + } 79 + 80 + #[serde_with::skip_serializing_none] 81 + #[derive(Debug, Serialize, Deserialize)] 82 + pub struct KeybindComponent { 83 + keybind: String, 84 + } 85 + 86 + #[derive(Debug, Serialize, Deserialize)] 87 + #[serde(rename_all = "snake_case")] 88 + pub enum NbtComponentSource { 89 + Block, 90 + Entity, 91 + Storage, 92 + } 93 + 94 + #[serde_with::skip_serializing_none] 95 + #[derive(Debug, Serialize, Deserialize)] 96 + pub struct NbtComponent { 97 + source: Option<NbtComponentSource>, 98 + #[serde(rename = "nbt")] 99 + path: String, 100 + interpret: Option<bool>, 101 + separator: Option<Box<Component>>, 102 + entity: Option<String>, 103 + block: Option<String>, 104 + storage: Option<Identifier>, 105 + } 106 + 107 + #[derive(Debug, Serialize, Deserialize)] 108 + #[serde(tag = "object", rename_all = "snake_case")] 109 + pub enum ObjectComponent { 110 + Atlas(AtlasObject), 111 + Player(PlayerObject), 112 + } 113 + 114 + #[serde_with::skip_serializing_none] 115 + #[derive(Debug, Serialize, Deserialize)] 116 + pub struct AtlasObject { 117 + atlas: Option<Identifier>, 118 + sprite: Identifier, 119 + } 120 + 121 + #[derive(Debug, Serialize, Deserialize)] 122 + #[serde(untagged)] 123 + pub enum PlayerProfileOrName { 124 + Profile(profile::PlayerProfile), 125 + Name(String), 126 + } 127 + 128 + #[serde_with::skip_serializing_none] 129 + #[derive(Debug, Serialize, Deserialize)] 130 + pub struct PlayerObject { 131 + player: PlayerProfileOrName, 132 + hat: Option<bool>, 133 + }
+31
nara_text/src/profile.rs
··· 1 + use serde::{Deserialize, Serialize}; 2 + 3 + use crate::Identifier; 4 + 5 + #[serde_with::skip_serializing_none] 6 + #[derive(Debug, Serialize, Deserialize)] 7 + pub struct PlayerProfile { 8 + name: Option<String>, 9 + id: Option<[i32; 4]>, // TODO(kokiriglade): use an actual UUID type 10 + #[serde(default, skip_serializing_if = "Vec::is_empty")] 11 + properties: Vec<PlayerProfileProperty>, 12 + texture: Option<Identifier>, 13 + cape: Option<Identifier>, 14 + elytra: Option<Identifier>, 15 + model: Option<PlayerModel>, 16 + } 17 + 18 + #[serde_with::skip_serializing_none] 19 + #[derive(Debug, Serialize, Deserialize)] 20 + pub struct PlayerProfileProperty { 21 + name: String, 22 + value: String, 23 + signature: Option<String>, 24 + } 25 + 26 + #[derive(Debug, Serialize, Deserialize)] 27 + #[serde(rename_all = "snake_case")] 28 + pub enum PlayerModel { 29 + Slim, 30 + Wide, 31 + }