steel_registry/
painting_variant.rs1use crate::{REGISTRY, RegistryExt, RegistryHolderEntry, RegistryTags};
2use rustc_hash::FxHashMap;
3use simdnbt::owned::{NbtCompound, NbtTag};
4use simdnbt::{FromNbtTag, ToNbtTag};
5use std::io::{Cursor, Result, Write};
6use steel_utils::Identifier;
7use steel_utils::hash::{ComponentHasher, HashComponent};
8use steel_utils::nbt::NbtNumeric as _;
9use steel_utils::serial::{ReadFrom, WriteTo};
10use text_components::TextComponent;
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct PaintingVariantValue {
14 pub width: i32,
15 pub height: i32,
16 pub asset_id: Identifier,
17 pub title: Option<TextComponent>,
18 pub author: Option<TextComponent>,
19}
20
21impl WriteTo for PaintingVariantValue {
22 fn write(&self, writer: &mut impl Write) -> Result<()> {
23 steel_utils::codec::VarInt(self.width).write(writer)?;
24 steel_utils::codec::VarInt(self.height).write(writer)?;
25 self.asset_id.write(writer)?;
26 self.title.write(writer)?;
27 self.author.write(writer)
28 }
29}
30
31impl ReadFrom for PaintingVariantValue {
32 fn read(data: &mut Cursor<&[u8]>) -> Result<Self> {
33 Ok(Self {
34 width: steel_utils::codec::VarInt::read(data)?.0,
35 height: steel_utils::codec::VarInt::read(data)?.0,
36 asset_id: Identifier::read(data)?,
37 title: Option::<TextComponent>::read(data)?,
38 author: Option::<TextComponent>::read(data)?,
39 })
40 }
41}
42
43impl ToNbtTag for PaintingVariantValue {
44 fn to_nbt_tag(self) -> NbtTag {
45 let mut compound = NbtCompound::new();
46 compound.insert("asset_id", self.asset_id.to_string());
47 compound.insert("width", self.width);
48 compound.insert("height", self.height);
49 if let Some(title) = self.title {
50 compound.insert("title", title.to_codec_nbt());
51 }
52 if let Some(author) = self.author {
53 compound.insert("author", author.to_codec_nbt());
54 }
55 NbtTag::Compound(compound)
56 }
57}
58
59impl FromNbtTag for PaintingVariantValue {
60 fn from_nbt_tag(tag: simdnbt::borrow::NbtTag) -> Option<Self> {
61 let compound = tag.compound()?;
62 let width = compound.get("width")?.codec_i32()?;
63 let height = compound.get("height")?.codec_i32()?;
64 if !(1..=16).contains(&width) || !(1..=16).contains(&height) {
65 return None;
66 }
67 Some(Self {
68 width,
69 height,
70 asset_id: Identifier::from_nbt_tag(compound.get("asset_id")?)?,
71 title: match compound.get("title") {
72 Some(tag) => Some(TextComponent::from_nbt(&tag.to_owned())?),
73 None => None,
74 },
75 author: match compound.get("author") {
76 Some(tag) => Some(TextComponent::from_nbt(&tag.to_owned())?),
77 None => None,
78 },
79 })
80 }
81}
82
83impl HashComponent for PaintingVariantValue {
84 fn hash_component(&self, hasher: &mut ComponentHasher) {
85 self.clone().to_nbt_tag().hash_component(hasher);
86 }
87}
88
89#[derive(Debug)]
91pub struct PaintingVariant {
92 pub key: Identifier,
93 value: PaintingVariantValue,
94}
95
96impl PaintingVariant {
97 #[must_use]
98 pub const fn new(key: Identifier, value: PaintingVariantValue) -> Self {
99 Self { key, value }
100 }
101 #[must_use]
102 pub const fn value(&self) -> &PaintingVariantValue {
103 &self.value
104 }
105}
106
107impl ToNbtTag for &PaintingVariant {
108 fn to_nbt_tag(self) -> NbtTag {
109 self.value.clone().to_nbt_tag()
110 }
111}
112
113pub type PaintingVariantRef = &'static PaintingVariant;
114
115pub struct PaintingVariantRegistry {
116 painting_variants_by_id: Vec<PaintingVariantRef>,
117 painting_variants_by_key: FxHashMap<Identifier, usize>,
118 tags: RegistryTags,
119 allows_registering: bool,
120}
121
122impl PaintingVariantRegistry {
123 #[must_use]
124 pub fn new() -> Self {
125 Self {
126 painting_variants_by_id: Vec::new(),
127 painting_variants_by_key: FxHashMap::default(),
128 tags: RegistryTags::default(),
129 allows_registering: true,
130 }
131 }
132}
133
134crate::impl_standard_methods!(
135 PaintingVariantRegistry,
136 PaintingVariantRef,
137 painting_variants_by_id,
138 painting_variants_by_key,
139 allows_registering
140);
141
142crate::impl_registry!(
143 PaintingVariantRegistry,
144 PaintingVariant,
145 painting_variants_by_id,
146 painting_variants_by_key,
147 painting_variants
148);
149crate::impl_tagged_registry!(
150 PaintingVariantRegistry,
151 painting_variants_by_key,
152 "painting variant"
153);
154
155impl RegistryHolderEntry for PaintingVariant {
156 type Value = PaintingVariantValue;
157 const REGISTRY_NAME: &'static str = "painting variant";
158 fn holder_value(&self) -> &Self::Value {
159 &self.value
160 }
161 fn holder_by_id(id: usize) -> Option<&'static Self> {
162 REGISTRY.painting_variants.by_id(id)
163 }
164 fn holder_by_key(key: &Identifier) -> Option<&'static Self> {
165 REGISTRY.painting_variants.by_key(key)
166 }
167}