aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--azalea-block/azalea-block-macros/src/lib.rs30
-rw-r--r--azalea-block/azalea-block-macros/src/property/generate.rs18
-rw-r--r--azalea-block/src/generated.rs2
-rw-r--r--azalea-block/src/lib.rs13
5 files changed, 58 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27b349cb..99e30e83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ is breaking anyways, semantic versioning is not followed.
- Re-implement `Client::map_component` and `map_get_component`.
- Add an `EntityRef` type to simplify interactions with entities.
- `AccountTrait` was implemented, which allows for custom refresh and join behavior for `Account`s.
+- Add `BlockTrait::set_property` to allow setting properties on blocks generically.
### Changed
diff --git a/azalea-block/azalea-block-macros/src/lib.rs b/azalea-block/azalea-block-macros/src/lib.rs
index 586d6a98..23546a2b 100644
--- a/azalea-block/azalea-block-macros/src/lib.rs
+++ b/azalea-block/azalea-block-macros/src/lib.rs
@@ -434,7 +434,8 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
});
let mut property_map_inner = quote! {};
- let mut get_property_inner = quote! {};
+ let mut get_property_match_inner = quote! {};
+ let mut set_property_match_inner = quote! {};
for PropertyWithNameAndDefault {
name,
@@ -450,10 +451,30 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
property_map_inner.extend(quote! {
map.insert(#name, #variant_name_tokens);
});
- get_property_inner.extend(quote! {
+ get_property_match_inner.extend(quote! {
#name => Some(#variant_name_tokens),
});
+
+ set_property_match_inner.extend(match kind {
+ PropertyKind::Enum => quote! { #name => self.#name_ident = new_value.parse()?, },
+ PropertyKind::Bool => {
+ quote! { #name => self.#name_ident = new_value.parse::<bool>().map_err(|_| ())?, }
+ }
+ });
}
+ let set_property = if set_property_match_inner.is_empty() {
+ quote! {
+ Err(())
+ }
+ } else {
+ quote! {
+ match name {
+ #set_property_match_inner
+ _ => return Err(()),
+ }
+ Ok(())
+ }
+ };
let mut block_default_fields = quote! {};
for PropertyWithNameAndDefault {
@@ -502,10 +523,13 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
}
fn get_property(&self, name: &str) -> Option<&'static str> {
match name {
- #get_property_inner
+ #get_property_match_inner
_ => None,
}
}
+ fn set_property(&mut self, name: &str, new_value: &str) -> Result<(), ()> {
+ #set_property
+ }
}
impl From<#block_struct_name> for BlockState {
diff --git a/azalea-block/azalea-block-macros/src/property/generate.rs b/azalea-block/azalea-block-macros/src/property/generate.rs
index c49afd53..fc48e609 100644
--- a/azalea-block/azalea-block-macros/src/property/generate.rs
+++ b/azalea-block/azalea-block-macros/src/property/generate.rs
@@ -36,6 +36,7 @@ fn generate_property_code(
let property_struct_name = get_property_type_name(&property.data);
let mut to_static_str_inner = quote! {};
+ let mut from_str_match_inner = quote! {};
match &property.data {
PropertyData::Enum { variants, .. } => {
@@ -56,6 +57,9 @@ fn generate_property_code(
to_static_str_inner.extend(quote! {
Self::#variant_ident => #variant_str,
});
+ from_str_match_inner.extend(quote! {
+ #variant_str => Self::#variant_ident,
+ });
}
properties_code.extend(quote! {
@@ -79,6 +83,10 @@ fn generate_property_code(
Self(true) => "true",
Self(false) => "false",
});
+ from_str_match_inner.extend(quote! {
+ "true" => Self(true),
+ "false" => Self(false),
+ });
properties_code.extend(quote! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -122,6 +130,16 @@ fn generate_property_code(
}
}
}
+ impl FromStr for #property_struct_name {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ #from_str_match_inner
+ _ => return Err(())
+ })
+ }
+ }
impl std::fmt::Display for #property_struct_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
diff --git a/azalea-block/src/generated.rs b/azalea-block/src/generated.rs
index 8d91695f..d042da22 100644
--- a/azalea-block/src/generated.rs
+++ b/azalea-block/src/generated.rs
@@ -1,6 +1,6 @@
//! This code is @generated by codegen/genblocks.py.
-use std::fmt::Debug;
+use std::{fmt::Debug, str::FromStr};
use azalea_block_macros::make_block_states;
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs
index ad78102c..3c64af25 100644
--- a/azalea-block/src/lib.rs
+++ b/azalea-block/src/lib.rs
@@ -7,7 +7,7 @@ mod generated;
mod range;
use core::fmt::Debug;
-use std::{any::Any, collections::HashMap};
+use std::{any::Any, collections::HashMap, str::FromStr};
use azalea_registry::builtin::BlockKind;
pub use behavior::BlockBehavior;
@@ -43,7 +43,16 @@ pub trait BlockTrait: Debug + Any {
/// has no property with that name.
///
/// To get all properties, you may use [`Self::property_map`].
+ ///
+ /// To set a property, use [`Self::set_property`].
fn get_property(&self, name: &str) -> Option<&'static str>;
+ /// Update a property on this block, with the name and value being strings.
+ ///
+ /// Returns `Ok(())`, if the property name and value are valid, otherwise it
+ /// returns `Err(())`.
+ ///
+ /// To get a property, use [`Self::get_property`].
+ fn set_property(&mut self, name: &str, new_value: &str) -> Result<(), ()>;
}
impl dyn BlockTrait {
@@ -52,7 +61,7 @@ impl dyn BlockTrait {
}
}
-pub trait Property {
+pub trait Property: FromStr {
type Value;
fn try_from_block_state(state: BlockState) -> Option<Self::Value>;