mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
make ResourceLocation::new -> Self and impl Serialize/Deserialize for ResourceLocation
This commit is contained in:
parent
1ff2495962
commit
aa846bc027
14 changed files with 94 additions and 51 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -433,6 +433,7 @@ dependencies = [
|
|||
"azalea-buf",
|
||||
"azalea-registry-macros",
|
||||
"enum-as-inner",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2055,18 +2056,18 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
version = "1.0.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
checksum = "71f2b4817415c6d4210bfe1c7bfcf4801b2d904cb4d0e1a8fdb651013c9e86b8"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
version = "1.0.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -265,7 +265,7 @@ fn process_packet_events(ecs: &mut World) {
|
|||
// brand
|
||||
local_player.write_packet(
|
||||
ServerboundCustomPayloadPacket {
|
||||
identifier: ResourceLocation::new("brand").unwrap(),
|
||||
identifier: ResourceLocation::new("brand"),
|
||||
// they don't have to know :)
|
||||
data: "vanilla".into(),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(const_for)]
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(generic_const_exprs)]
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@ use std::io::{Cursor, Write};
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
// TODO: make a `resourcelocation!("minecraft:overworld")` macro that checks if
|
||||
// it's correct at compile-time.
|
||||
|
||||
#[derive(Hash, Clone, PartialEq, Eq)]
|
||||
pub struct ResourceLocation {
|
||||
pub namespace: String,
|
||||
|
@ -19,7 +16,7 @@ static DEFAULT_NAMESPACE: &str = "minecraft";
|
|||
// static REALMS_NAMESPACE: &str = "realms";
|
||||
|
||||
impl ResourceLocation {
|
||||
pub fn new(resource_string: &str) -> Result<ResourceLocation, BufReadError> {
|
||||
pub fn new(resource_string: &str) -> ResourceLocation {
|
||||
let sep_byte_position_option = resource_string.chars().position(|c| c == ':');
|
||||
let (namespace, path) = if let Some(sep_byte_position) = sep_byte_position_option {
|
||||
if sep_byte_position == 0 {
|
||||
|
@ -33,10 +30,10 @@ impl ResourceLocation {
|
|||
} else {
|
||||
(DEFAULT_NAMESPACE, resource_string)
|
||||
};
|
||||
Ok(ResourceLocation {
|
||||
ResourceLocation {
|
||||
namespace: namespace.to_string(),
|
||||
path: path.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +51,7 @@ impl std::fmt::Debug for ResourceLocation {
|
|||
impl McBufReadable for ResourceLocation {
|
||||
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||
let location_string = String::read_from(buf)?;
|
||||
ResourceLocation::new(&location_string)
|
||||
Ok(ResourceLocation::new(&location_string))
|
||||
}
|
||||
}
|
||||
impl McBufWritable for ResourceLocation {
|
||||
|
@ -81,10 +78,7 @@ impl<'de> Deserialize<'de> for ResourceLocation {
|
|||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
if s.contains(':') {
|
||||
match ResourceLocation::new(&s) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(e) => Err(de::Error::custom(e)),
|
||||
}
|
||||
Ok(ResourceLocation::new(&s))
|
||||
} else {
|
||||
Err(de::Error::invalid_value(
|
||||
de::Unexpected::Str(&s),
|
||||
|
@ -100,25 +94,25 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn basic_resource_location() {
|
||||
let r = ResourceLocation::new("abcdef:ghijkl").unwrap();
|
||||
let r = ResourceLocation::new("abcdef:ghijkl");
|
||||
assert_eq!(r.namespace, "abcdef");
|
||||
assert_eq!(r.path, "ghijkl");
|
||||
}
|
||||
#[test]
|
||||
fn no_namespace() {
|
||||
let r = ResourceLocation::new("azalea").unwrap();
|
||||
let r = ResourceLocation::new("azalea");
|
||||
assert_eq!(r.namespace, "minecraft");
|
||||
assert_eq!(r.path, "azalea");
|
||||
}
|
||||
#[test]
|
||||
fn colon_start() {
|
||||
let r = ResourceLocation::new(":azalea").unwrap();
|
||||
let r = ResourceLocation::new(":azalea");
|
||||
assert_eq!(r.namespace, "minecraft");
|
||||
assert_eq!(r.path, "azalea");
|
||||
}
|
||||
#[test]
|
||||
fn colon_end() {
|
||||
let r = ResourceLocation::new("azalea:").unwrap();
|
||||
let r = ResourceLocation::new("azalea:");
|
||||
assert_eq!(r.namespace, "azalea");
|
||||
assert_eq!(r.path, "");
|
||||
}
|
||||
|
@ -127,7 +121,6 @@ mod tests {
|
|||
fn mcbuf_resource_location() {
|
||||
let mut buf = Vec::new();
|
||||
ResourceLocation::new("minecraft:dirt")
|
||||
.unwrap()
|
||||
.write_into(&mut buf)
|
||||
.unwrap();
|
||||
|
||||
|
@ -135,7 +128,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
ResourceLocation::read_from(&mut buf).unwrap(),
|
||||
ResourceLocation::new("minecraft:dirt").unwrap()
|
||||
ResourceLocation::new("minecraft:dirt")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -326,7 +326,7 @@ mod tests {
|
|||
fn test_gravity() {
|
||||
let mut app = make_test_app();
|
||||
let _world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -342,7 +342,7 @@ mod tests {
|
|||
z: 0.,
|
||||
},
|
||||
azalea_registry::EntityKind::Zombie,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
@ -378,7 +378,7 @@ mod tests {
|
|||
fn test_collision() {
|
||||
let mut app = make_test_app();
|
||||
let world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -400,7 +400,7 @@ mod tests {
|
|||
z: 0.5,
|
||||
},
|
||||
azalea_registry::EntityKind::Player,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
@ -437,7 +437,7 @@ mod tests {
|
|||
fn test_slab_collision() {
|
||||
let mut app = make_test_app();
|
||||
let world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -459,7 +459,7 @@ mod tests {
|
|||
z: 0.5,
|
||||
},
|
||||
azalea_registry::EntityKind::Player,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
@ -491,7 +491,7 @@ mod tests {
|
|||
fn test_top_slab_collision() {
|
||||
let mut app = make_test_app();
|
||||
let world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -513,7 +513,7 @@ mod tests {
|
|||
z: 0.5,
|
||||
},
|
||||
azalea_registry::EntityKind::Player,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
@ -544,7 +544,7 @@ mod tests {
|
|||
fn test_weird_wall_collision() {
|
||||
let mut app = make_test_app();
|
||||
let world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -566,7 +566,7 @@ mod tests {
|
|||
z: 0.5,
|
||||
},
|
||||
azalea_registry::EntityKind::Player,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
@ -602,7 +602,7 @@ mod tests {
|
|||
fn test_negative_coordinates_weird_wall_collision() {
|
||||
let mut app = make_test_app();
|
||||
let world_lock = app.world.resource_mut::<InstanceContainer>().insert(
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
384,
|
||||
-64,
|
||||
);
|
||||
|
@ -624,7 +624,7 @@ mod tests {
|
|||
z: -7.5,
|
||||
},
|
||||
azalea_registry::EntityKind::Player,
|
||||
ResourceLocation::new("minecraft:overworld").unwrap(),
|
||||
ResourceLocation::new("minecraft:overworld"),
|
||||
),
|
||||
MinecraftEntityId(0),
|
||||
Local,
|
||||
|
|
|
@ -21,9 +21,13 @@ azalea-brigadier = { path = "../azalea-brigadier", version = "^0.6.0", features
|
|||
] }
|
||||
azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
|
||||
azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
|
||||
azalea-core = { path = "../azalea-core", optional = true, version = "^0.6.0", features = ["serde"]}
|
||||
azalea-core = { path = "../azalea-core", optional = true, version = "^0.6.0", features = [
|
||||
"serde",
|
||||
] }
|
||||
azalea-crypto = { path = "../azalea-crypto", version = "^0.6.0" }
|
||||
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0", features = ["serde"] }
|
||||
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0", features = [
|
||||
"serde",
|
||||
] }
|
||||
azalea-protocol-macros = { path = "./azalea-protocol-macros", version = "^0.6.0" }
|
||||
azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
|
||||
azalea-world = { path = "../azalea-world", version = "^0.6.0" }
|
||||
|
|
|
@ -364,7 +364,7 @@ mod tests {
|
|||
node_type: NodeType::Argument {
|
||||
name: "position".to_string(),
|
||||
parser: BrigadierParser::Vec3,
|
||||
suggestions_type: Some(ResourceLocation::new("minecraft:test_suggestion").unwrap()),
|
||||
suggestions_type: Some(ResourceLocation::new("minecraft:test_suggestion")),
|
||||
},
|
||||
};
|
||||
let mut buf = Vec::new();
|
||||
|
|
|
@ -348,7 +348,7 @@ pub mod registry {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "strict_registry", serde(deny_unknown_fields))]
|
||||
pub struct SoundId {
|
||||
pub sound_id: ResourceLocation,
|
||||
pub sound_id: azalea_registry::SoundEvent,
|
||||
}
|
||||
|
||||
/// Biome particles.
|
||||
|
@ -445,7 +445,7 @@ mod tests {
|
|||
root: RegistryRoot {
|
||||
chat_type: Tag::End,
|
||||
dimension_type: RegistryType::<DimensionTypeElement> {
|
||||
kind: ResourceLocation::new("minecraft:dimension_type").unwrap(),
|
||||
kind: ResourceLocation::new("minecraft:dimension_type"),
|
||||
value: Vec::new(),
|
||||
},
|
||||
world_type: Tag::End,
|
||||
|
|
|
@ -124,7 +124,7 @@ mod tests {
|
|||
let packet = ClientboundUpdateAdvancementsPacket {
|
||||
reset: true,
|
||||
added: [(
|
||||
ResourceLocation::new("minecraft:test").unwrap(),
|
||||
ResourceLocation::new("minecraft:test"),
|
||||
Advancement {
|
||||
parent_id: None,
|
||||
display: Some(DisplayInfo {
|
||||
|
@ -144,11 +144,11 @@ mod tests {
|
|||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
removed: vec![ResourceLocation::new("minecraft:test2").unwrap()],
|
||||
removed: vec![ResourceLocation::new("minecraft:test2")],
|
||||
progress: [(
|
||||
ResourceLocation::new("minecraft:test3").unwrap(),
|
||||
ResourceLocation::new("minecraft:test3"),
|
||||
[(
|
||||
ResourceLocation::new("minecraft:test4").unwrap(),
|
||||
ResourceLocation::new("minecraft:test4"),
|
||||
CriterionProgress {
|
||||
date: Some(123456789),
|
||||
},
|
||||
|
@ -170,12 +170,12 @@ mod tests {
|
|||
|
||||
let advancement = packet
|
||||
.added
|
||||
.get(&ResourceLocation::new("minecraft:test").unwrap())
|
||||
.get(&ResourceLocation::new("minecraft:test"))
|
||||
.unwrap()
|
||||
.clone();
|
||||
let read_advancement = read_packet
|
||||
.added
|
||||
.get(&ResourceLocation::new("minecraft:test").unwrap())
|
||||
.get(&ResourceLocation::new("minecraft:test"))
|
||||
.unwrap()
|
||||
.clone();
|
||||
assert_eq!(advancement.parent_id, read_advancement.parent_id);
|
||||
|
|
|
@ -182,9 +182,7 @@ impl McBufWritable for Recipe {
|
|||
RecipeData::Stonecutting(_) => "minecraft:stonecutting",
|
||||
RecipeData::Smithing(_) => "minecraft:smithing",
|
||||
};
|
||||
ResourceLocation::new(resource_location)
|
||||
.unwrap()
|
||||
.write_into(buf)?;
|
||||
ResourceLocation::new(resource_location).write_into(buf)?;
|
||||
self.identifier.write_into(buf)?;
|
||||
self.data.write_without_id(buf)?;
|
||||
Ok(())
|
||||
|
|
|
@ -9,6 +9,11 @@ version = "0.6.0"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
azalea-buf = {path = "../azalea-buf", version = "^0.6.0" }
|
||||
azalea-registry-macros = {path = "./azalea-registry-macros", version = "^0.6.0" }
|
||||
azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
|
||||
azalea-registry-macros = { path = "./azalea-registry-macros", version = "^0.6.0" }
|
||||
enum-as-inner = "0.5.1"
|
||||
serde = { version = "1.0.155", optional = true }
|
||||
|
||||
[features]
|
||||
serde = ["dep:serde", "azalea-registry-macros/serde"]
|
||||
default = ["serde"]
|
||||
|
|
|
@ -15,3 +15,6 @@ proc-macro = true
|
|||
proc-macro2 = "1.0.39"
|
||||
quote = "1.0.18"
|
||||
syn = "1.0.95"
|
||||
|
||||
[features]
|
||||
serde = []
|
||||
|
|
|
@ -136,12 +136,16 @@ pub fn registry(input: TokenStream) -> TokenStream {
|
|||
|
||||
// Display that uses registry ids
|
||||
let mut display_items = quote! {};
|
||||
let mut from_str_items = quote! {};
|
||||
for item in &input.items {
|
||||
let name = &item.name;
|
||||
let id = &item.id;
|
||||
display_items.extend(quote! {
|
||||
Self::#name => write!(f, #id),
|
||||
});
|
||||
from_str_items.extend(quote! {
|
||||
#id => Ok(Self::#name),
|
||||
});
|
||||
}
|
||||
generated.extend(quote! {
|
||||
impl std::fmt::Display for #name {
|
||||
|
@ -151,7 +155,40 @@ pub fn registry(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl std::str::FromStr for #name {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
#from_str_items
|
||||
_ => Err(format!("{s:?} is not a valid {name}", s = s, name = stringify!(#name))),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
{
|
||||
generated.extend(quote! {
|
||||
impl serde::Serialize for #name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
impl<'de> serde::Deserialize<'de> for #name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
s.parse().map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
generated.into()
|
||||
}
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
// auto-generated (so you can add doc comments to the registry enums if you
|
||||
// want)
|
||||
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
|
||||
use azalea_registry_macros::registry;
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
pub trait Registry
|
||||
where
|
||||
|
|
Loading…
Add table
Reference in a new issue