1#![doc = include_str!("../README.md")]
2
3pub mod builtin;
9pub mod data;
10pub mod identifier;
11pub mod tags;
12
13use std::{
14 fmt::{self, Debug},
15 hash::Hash,
16 io::{self, Cursor, Write},
17};
18
19use azalea_buf::{AzBuf, AzBufVar, BufReadError};
20#[cfg(feature = "serde")]
21use serde::Serialize;
22use simdnbt::{FromNbtTag, borrow::NbtTag};
23
24use crate::identifier::Identifier;
25
26macro_rules! define_deprecated_builtin {
28 ($($r:ident) *) => {
29 $(
30 #[doc(hidden)]
31 #[deprecated = concat!("moved to `azalea_registry::builtin::", stringify!($r), "`")]
32 pub type $r = builtin::$r;
33 )*
34 };
35}
36define_deprecated_builtin!(Activity Attribute BlockEntityKind BlockPredicateKind ChunkStatus CommandArgumentKind CustomStat EntityKind FloatProviderKind Fluid GameEvent HeightProviderKind IntProviderKind LootConditionKind LootFunctionKind LootNbtProviderKind LootNumberProviderKind LootPoolEntryKind LootScoreProviderKind MemoryModuleKind MobEffect ParticleKind PointOfInterestKind PosRuleTest PositionSourceKind Potion RecipeSerializer RecipeKind RuleTest SensorKind SoundEvent StatKind VillagerProfession VillagerKind WorldgenBiomeSource WorldgenBlockStateProviderKind WorldgenCarver WorldgenChunkGenerator WorldgenDensityFunctionKind WorldgenFeature WorldgenFeatureSizeKind WorldgenFoliagePlacerKind WorldgenMaterialCondition WorldgenMaterialRule WorldgenPlacementModifierKind WorldgenRootPlacerKind WorldgenStructurePiece WorldgenStructurePlacement WorldgenStructurePoolElement WorldgenStructureProcessor WorldgenStructureKind WorldgenTreeDecoratorKind WorldgenTrunkPlacerKind RuleBlockEntityModifier CreativeModeTab MenuKind WorldgenPoolAliasBinding TriggerKind NumberFormatKind DataComponentKind EntitySubPredicateKind MapDecorationKind EnchantmentEffectComponentKind EnchantmentEntityEffectKind EnchantmentLevelBasedValueKind EnchantmentLocationBasedEffectKind EnchantmentProviderKind EnchantmentValueEffectKind DecoratedPotPattern ConsumeEffectKind RecipeBookCategory RecipeDisplay SlotDisplay TicketKind TestEnvironmentDefinitionKind TestFunction TestInstanceKind DataComponentPredicateKind SpawnConditionKind DialogBodyKind DialogKind InputControlKind DialogActionKind DebugSubscription IncomingRpcMethods OutgoingRpcMethods AttributeKind EnvironmentAttribute GameRule PermissionCheckKind PermissionKind SlotSourceKind);
37macro_rules! define_deprecated_data {
38 ($($r:ident) *) => {
39 $(
40 #[doc(hidden)]
41 #[deprecated = concat!("moved to `azalea_registry::data::", stringify!($r), "`")]
42 pub type $r = data::$r;
43 )*
44 };
45}
46define_deprecated_data!(Enchantment DamageKind Dialog WolfSoundVariant CowVariant ChickenVariant FrogVariant CatVariant PigVariant PaintingVariant WolfVariant ZombieNautilusVariant Biome);
47
48#[doc(hidden)]
49#[deprecated = "renamed to `azalea_registry::builtin::ItemKind`"]
50pub type Item = builtin::ItemKind;
51#[doc(hidden)]
52#[deprecated = "renamed to `azalea_registry::builtin::BlockKind`"]
53pub type Block = builtin::BlockKind;
54#[doc(hidden)]
55#[deprecated = "renamed to `azalea_registry::data::DimensionKind`"]
56pub type DimensionType = data::DimensionKind;
57
58pub trait Registry: AzBuf + PartialEq + PartialOrd + Ord + Copy + Hash
59where
60 Self: Sized,
61{
62 fn from_u32(value: u32) -> Option<Self>;
63 fn to_u32(&self) -> u32;
64}
65
66#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
70pub struct OptionalRegistry<T: Registry>(pub Option<T>);
71
72impl<T: Registry> AzBuf for OptionalRegistry<T> {
73 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
74 Ok(OptionalRegistry(match u32::azalea_read_var(buf)? {
75 0 => None,
76 value => Some(
77 T::from_u32(value - 1)
78 .ok_or(BufReadError::UnexpectedEnumVariant { id: value as i32 })?,
79 ),
80 }))
81 }
82 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
83 match &self.0 {
84 None => 0u32.azalea_write_var(buf),
85 Some(value) => (value.to_u32() + 1).azalea_write_var(buf),
86 }
87 }
88}
89
90#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
92pub enum CustomRegistry<D: Registry, C: AzBuf> {
93 Direct(D),
94 Custom(C),
95}
96
97impl<D: Registry, C: AzBuf> AzBuf for CustomRegistry<D, C> {
98 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
99 let direct_registry = OptionalRegistry::<D>::azalea_read(buf)?;
100 if let Some(direct_registry) = direct_registry.0 {
101 return Ok(CustomRegistry::Direct(direct_registry));
102 }
103 Ok(CustomRegistry::Custom(C::azalea_read(buf)?))
104 }
105 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
106 match self {
107 CustomRegistry::Direct(direct_registry) => {
108 (direct_registry.to_u32() + 1).azalea_write_var(buf)
110 }
111 CustomRegistry::Custom(custom_registry) => {
112 0u32.azalea_write_var(buf)?;
114 custom_registry.azalea_write(buf)
115 }
116 }
117 }
118}
119
120#[derive(Clone, PartialEq)]
121pub enum HolderSet<D: Registry, Identifier: AzBuf> {
122 Direct {
123 contents: Vec<D>,
124 },
125 Named {
126 key: Identifier,
127 contents: Vec<Identifier>,
128 },
129}
130impl<D: Registry, Identifier: AzBuf> AzBuf for HolderSet<D, Identifier> {
131 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
132 let size = i32::azalea_read_var(buf)?.wrapping_sub(1);
133 if size == -1 {
134 let key = Identifier::azalea_read(buf)?;
135 Ok(Self::Named {
136 key,
137 contents: Vec::new(),
138 })
139 } else {
140 let mut contents = Vec::new();
141 for _ in 0..size {
142 contents.push(D::azalea_read(buf)?);
143 }
144 Ok(Self::Direct { contents })
145 }
146 }
147 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
148 match self {
149 Self::Direct { contents } => {
150 (contents.len() as i32 + 1).azalea_write_var(buf)?;
151 for item in contents {
152 item.azalea_write(buf)?;
153 }
154 }
155 Self::Named { key, contents: _ } => {
156 0i32.azalea_write_var(buf)?;
157 key.azalea_write(buf)?;
158 }
159 }
160 Ok(())
161 }
162}
163impl<D: Registry + Debug, Identifier: AzBuf + Debug> Debug for HolderSet<D, Identifier> {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 match self {
166 Self::Direct { contents } => f.debug_list().entries(contents).finish(),
167 Self::Named { key, contents } => f
168 .debug_struct("Named")
169 .field("key", key)
170 .field("contents", contents)
171 .finish(),
172 }
173 }
174}
175impl<D: Registry, Identifier: AzBuf> From<Vec<D>> for HolderSet<D, Identifier> {
176 fn from(contents: Vec<D>) -> Self {
177 Self::Direct { contents }
178 }
179}
180#[cfg(feature = "serde")]
181impl<D: Registry + Serialize, Identifier: AzBuf + Serialize> Serialize
182 for HolderSet<D, Identifier>
183{
184 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185 where
186 S: serde::Serializer,
187 {
188 match self {
189 Self::Direct { contents } => {
190 if contents.len() == 1 {
191 contents[0].serialize(serializer)
192 } else {
193 contents.serialize(serializer)
194 }
195 }
196 Self::Named { key, contents: _ } => key.serialize(serializer),
197 }
198 }
199}
200impl<D: Registry, Identifier: AzBuf> Default for HolderSet<D, Identifier> {
201 fn default() -> Self {
202 Self::Direct {
203 contents: Vec::new(),
204 }
205 }
206}
207impl<D: Registry, Identifier: AzBuf + From<D> + PartialEq> HolderSet<D, Identifier> {
208 pub fn contains(&self, value: D) -> bool {
209 match self {
210 HolderSet::Direct { contents } => contents.contains(&value),
211 HolderSet::Named { key: _, contents } => contents.contains(&Identifier::from(value)),
212 }
213 }
214}
215
216pub enum Holder<R: Registry, Direct: AzBuf> {
219 Reference(R),
220 Direct(Direct),
221}
222impl<R: Registry, Direct: AzBuf> AzBuf for Holder<R, Direct> {
223 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
224 let id = u32::azalea_read_var(buf)?;
225 if id == 0 {
226 Ok(Self::Direct(Direct::azalea_read(buf)?))
227 } else {
228 let id = id - 1;
229 let Some(value) = R::from_u32(id) else {
230 return Err(BufReadError::UnexpectedEnumVariant { id: id as i32 });
231 };
232 Ok(Self::Reference(value))
233 }
234 }
235 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
236 match self {
237 Self::Reference(value) => (value.to_u32() + 1).azalea_write_var(buf),
238 Self::Direct(value) => {
239 0u32.azalea_write_var(buf)?;
240 value.azalea_write(buf)
241 }
242 }
243 }
244}
245impl<R: Registry + Debug, Direct: AzBuf + Debug> Debug for Holder<R, Direct> {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 match self {
248 Self::Reference(value) => f.debug_tuple("Reference").field(value).finish(),
249 Self::Direct(value) => f.debug_tuple("Direct").field(value).finish(),
250 }
251 }
252}
253impl<R: Registry + Clone, Direct: AzBuf + Clone> Clone for Holder<R, Direct> {
254 fn clone(&self) -> Self {
255 match self {
256 Self::Reference(value) => Self::Reference(*value),
257 Self::Direct(value) => Self::Direct(value.clone()),
258 }
259 }
260}
261impl<R: Registry + PartialEq, Direct: AzBuf + PartialEq> PartialEq for Holder<R, Direct> {
262 fn eq(&self, other: &Self) -> bool {
263 match (self, other) {
264 (Self::Reference(a), Self::Reference(b)) => a == b,
265 (Self::Direct(a), Self::Direct(b)) => a == b,
266 _ => false,
267 }
268 }
269}
270impl<R: Registry + Default, Direct: AzBuf> Default for Holder<R, Direct> {
271 fn default() -> Self {
272 Self::Reference(R::default())
273 }
274}
275#[cfg(feature = "serde")]
276impl<R: Registry + Serialize, Direct: AzBuf + Serialize> Serialize for Holder<R, Direct> {
277 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
278 where
279 S: serde::Serializer,
280 {
281 match self {
282 Self::Reference(value) => value.serialize(serializer),
283 Self::Direct(value) => value.serialize(serializer),
284 }
285 }
286}
287
288impl<R: Registry + FromNbtTag, Direct: AzBuf + FromNbtTag> FromNbtTag for Holder<R, Direct> {
289 fn from_nbt_tag(tag: NbtTag) -> Option<Self> {
290 if let Some(reference) = R::from_nbt_tag(tag) {
291 return Some(Self::Reference(reference));
292 };
293 Direct::from_nbt_tag(tag).map(Self::Direct)
294 }
295}
296
297pub trait DataRegistry: AzBuf + PartialEq + PartialOrd + Ord + Copy + Hash {
303 const NAME: &'static str;
304 type Key: DataRegistryKey;
305
306 fn protocol_id(&self) -> u32;
307 fn new_raw(id: u32) -> Self;
308}
309pub trait DataRegistryKey {
310 type Borrow<'a>: DataRegistryKeyRef<'a>;
311
312 fn from_ident(ident: Identifier) -> Self;
313 fn into_ident(self) -> Identifier;
314}
315pub trait DataRegistryKeyRef<'a> {
316 type Owned: DataRegistryKey;
317
318 fn to_owned(self) -> Self::Owned;
319 fn from_ident(ident: &'a Identifier) -> Self;
320 fn into_ident(self) -> Identifier;
321}
322impl<T: DataRegistry> Registry for T {
323 fn from_u32(value: u32) -> Option<Self> {
324 Some(Self::new_raw(value))
325 }
326
327 fn to_u32(&self) -> u32 {
328 self.protocol_id()
329 }
330}