Skip to main content

steel_registry/
painting_variant.rs

1use 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/// Represents a painting variant definition from a data pack JSON file.
90#[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}