fix: data component try_from_name
This commit is contained in:
parent
ee6e0474ff
commit
e5047bd4c9
@ -54,10 +54,17 @@ pub struct EnchantmentsImpl {
|
||||
}
|
||||
impl EnchantmentsImpl {
|
||||
pub fn read_data(data: &NbtTag) -> Option<Self> {
|
||||
let data = &data.extract_compound()?.child_tags;
|
||||
let compound = data.extract_compound()?;
|
||||
let data = if let Some(NbtTag::Compound(levels)) = compound.child_tags.get("levels") {
|
||||
&levels.child_tags
|
||||
} else {
|
||||
&compound.child_tags
|
||||
};
|
||||
let mut enc = Vec::with_capacity(data.len());
|
||||
for (name, level) in data {
|
||||
enc.push((Enchantment::from_name(name.as_ref())?, level.extract_int()?));
|
||||
let enchantment = Enchantment::from_name(name.as_ref())
|
||||
.or_else(|| Enchantment::from_name(&format!("minecraft:{name}")))?;
|
||||
enc.push((enchantment, level.extract_int()?));
|
||||
}
|
||||
Some(Self {
|
||||
enchantment: Cow::from(enc),
|
||||
@ -597,10 +604,17 @@ pub struct StoredEnchantmentsImpl {
|
||||
}
|
||||
impl StoredEnchantmentsImpl {
|
||||
pub fn read_data(data: &NbtTag) -> Option<Self> {
|
||||
let data = &data.extract_compound()?.child_tags;
|
||||
let compound = data.extract_compound()?;
|
||||
let data = if let Some(NbtTag::Compound(levels)) = compound.child_tags.get("levels") {
|
||||
&levels.child_tags
|
||||
} else {
|
||||
&compound.child_tags
|
||||
};
|
||||
let mut enc = Vec::with_capacity(data.len());
|
||||
for (name, level) in data {
|
||||
enc.push((Enchantment::from_name(name.as_ref())?, level.extract_int()?));
|
||||
let enchantment = Enchantment::from_name(name.as_ref())
|
||||
.or_else(|| Enchantment::from_name(&format!("minecraft:{name}")))?;
|
||||
enc.push((enchantment, level.extract_int()?));
|
||||
}
|
||||
Some(Self {
|
||||
enchantment: Cow::from(enc),
|
||||
|
||||
@ -42,9 +42,11 @@ impl Clone for Box<dyn DataComponentImpl> {
|
||||
pub fn get<T: DataComponentImpl + 'static>(value: &dyn DataComponentImpl) -> &T {
|
||||
value.as_any().downcast_ref::<T>().unwrap_or_else(|| {
|
||||
panic!(
|
||||
"you are trying to cast {} to {}",
|
||||
"you are trying to cast {} ({}) to {} ({})",
|
||||
value.get_self_enum().to_name(),
|
||||
T::get_enum().to_name()
|
||||
std::any::type_name_of_val(value),
|
||||
T::get_enum().to_name(),
|
||||
std::any::type_name::<T>()
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -52,10 +54,12 @@ pub fn get<T: DataComponentImpl + 'static>(value: &dyn DataComponentImpl) -> &T
|
||||
#[inline]
|
||||
pub fn get_mut<T: DataComponentImpl + 'static>(value: &mut dyn DataComponentImpl) -> &mut T {
|
||||
let name = value.get_self_enum().to_name();
|
||||
let val_type = std::any::type_name_of_val(value);
|
||||
value.as_mut_any().downcast_mut::<T>().unwrap_or_else(|| {
|
||||
panic!(
|
||||
"you are trying to cast {name} to {}",
|
||||
T::get_enum().to_name()
|
||||
"you are trying to cast {name} ({val_type}) to {} ({})",
|
||||
T::get_enum().to_name(),
|
||||
std::any::type_name::<T>()
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -63,7 +67,11 @@ pub fn get_mut<T: DataComponentImpl + 'static>(value: &mut dyn DataComponentImpl
|
||||
macro_rules! default_impl {
|
||||
($t: ident) => {
|
||||
fn equal(&self, other: &dyn crate::data_component_impl::DataComponentImpl) -> bool {
|
||||
self == crate::data_component_impl::get::<Self>(other)
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
self == other
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn get_enum() -> crate::data_component::DataComponent
|
||||
@ -745,4 +753,33 @@ mod tests {
|
||||
);
|
||||
assert_round_trip(LockImpl { predicate }, LockImpl::read_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equal_with_different_types_returns_false() {
|
||||
let enc = EnchantmentsImpl {
|
||||
enchantment: Cow::Borrowed(&[(&crate::Enchantment::SHARPNESS, 2)]),
|
||||
};
|
||||
let max_stack = MaxStackSizeImpl { size: 64 };
|
||||
assert!(!enc.equal(&max_stack));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enchantments_read_data_formats() {
|
||||
let mut direct = NbtCompound::new();
|
||||
direct.put_int("sharpness", 2);
|
||||
let enc1 = EnchantmentsImpl::read_data(&NbtTag::Compound(direct)).unwrap();
|
||||
assert!(enc1.enchantment[0].0 == &crate::Enchantment::SHARPNESS);
|
||||
assert_eq!(enc1.enchantment[0].1, 2);
|
||||
|
||||
let mut levels = NbtCompound::new();
|
||||
levels.put_int("minecraft:sharpness", 2);
|
||||
let mut wrapped = NbtCompound::new();
|
||||
wrapped
|
||||
.child_tags
|
||||
.insert("levels".into(), NbtTag::Compound(levels));
|
||||
let enc2 = EnchantmentsImpl::read_data(&NbtTag::Compound(wrapped)).unwrap();
|
||||
assert_eq!(enc2.enchantment.len(), 1);
|
||||
assert!(enc2.enchantment[0].0 == &crate::Enchantment::SHARPNESS);
|
||||
assert_eq!(enc2.enchantment[0].1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,7 +240,12 @@ impl DataComponent {
|
||||
#[must_use]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn try_from_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
let name = if name.contains(':') {
|
||||
std::borrow::Cow::Borrowed(name)
|
||||
} else {
|
||||
std::borrow::Cow::Owned(format!("minecraft:{name}"))
|
||||
};
|
||||
match name.as_ref() {
|
||||
"minecraft:custom_data" => Some(Self::CustomData),
|
||||
"minecraft:max_stack_size" => Some(Self::MaxStackSize),
|
||||
"minecraft:max_damage" => Some(Self::MaxDamage),
|
||||
|
||||
@ -984,7 +984,12 @@ impl Enchantment {
|
||||
},
|
||||
};
|
||||
pub fn from_name(name: &str) -> Option<&'static Self> {
|
||||
match name {
|
||||
let name = if name.contains(':') {
|
||||
std::borrow::Cow::Borrowed(name)
|
||||
} else {
|
||||
std::borrow::Cow::Owned(format!("minecraft:{name}"))
|
||||
};
|
||||
match name.as_ref() {
|
||||
"minecraft:aqua_affinity" => Some(&Self::AQUA_AFFINITY),
|
||||
"minecraft:bane_of_arthropods" => Some(&Self::BANE_OF_ARTHROPODS),
|
||||
"minecraft:binding_curse" => Some(&Self::BINDING_CURSE),
|
||||
|
||||
@ -36,7 +36,7 @@ pub fn build() -> TokenStream {
|
||||
|
||||
// TODO use phf
|
||||
name_to_enum.extend(quote! {
|
||||
#raw_name => Some(Self::#pascal_case),
|
||||
#raw_name | #strip_name => Some(Self::#pascal_case),
|
||||
});
|
||||
|
||||
// Enum -> &str
|
||||
|
||||
@ -187,7 +187,7 @@ pub fn build() -> TokenStream {
|
||||
}]);
|
||||
}
|
||||
|
||||
name_to_type.extend(quote! { #name => Some(&Self::#format_name), });
|
||||
name_to_type.extend(quote! { #name | #raw_name => Some(&Self::#format_name), });
|
||||
id_to_type.extend(quote! { #id => Some(&Self::#format_name), });
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user