aboutsummaryrefslogtreecommitdiff
path: root/azalea-core/src/identifier.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-12-09 13:29:59 -0600
committerGitHub <noreply@github.com>2025-12-09 13:29:59 -0600
commit26d619c9a329087a23d6577ee74bd764f50cd773 (patch)
tree8020fe902257764a23a445c6ed9987ea4848189d /azalea-core/src/identifier.rs
parent84cd261118c9d1e3145d4d1751c0d22098cd8cd8 (diff)
downloadazalea-drasl-26d619c9a329087a23d6577ee74bd764f50cd773.tar.xz
Enchantments (#286)
* start implementing enchants * store parsed registries * more work on enchants * implement deserializer for some entity effects * mostly working definitions for enchants * fix tests * detect equipment changes * fix errors * update changelog * fix some imports * remove outdated todo * add basic test for enchants applying attributes * use git simdnbt
Diffstat (limited to 'azalea-core/src/identifier.rs')
-rw-r--r--azalea-core/src/identifier.rs78
1 files changed, 49 insertions, 29 deletions
diff --git a/azalea-core/src/identifier.rs b/azalea-core/src/identifier.rs
index 117bf26d..a3c886c3 100644
--- a/azalea-core/src/identifier.rs
+++ b/azalea-core/src/identifier.rs
@@ -1,8 +1,9 @@
//! An arbitrary identifier or resource location.
use std::{
- fmt,
+ fmt::{self, Debug, Display},
io::{self, Cursor, Write},
+ num::NonZeroUsize,
str::FromStr,
};
@@ -16,43 +17,62 @@ use simdnbt::{FromNbtTag, ToNbtTag, owned::NbtTag};
#[doc(alias = "ResourceLocation")]
#[derive(Hash, Clone, PartialEq, Eq, Default)]
pub struct Identifier {
- pub namespace: String,
- pub path: String,
+ // empty namespaces aren't allowed so NonZero is fine.
+ colon_index: Option<NonZeroUsize>,
+ inner: Box<str>,
}
static DEFAULT_NAMESPACE: &str = "minecraft";
// static REALMS_NAMESPACE: &str = "realms";
impl Identifier {
- pub fn new(resource_string: &str) -> Identifier {
- 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 {
- (DEFAULT_NAMESPACE, &resource_string[1..])
- } else {
- (
- &resource_string[..sep_byte_position],
- &resource_string[sep_byte_position + 1..],
- )
+ pub fn new(resource_string: impl Into<String>) -> Identifier {
+ let mut resource_string = resource_string.into();
+
+ let colon_index = resource_string.find(':');
+ let colon_index = if let Some(colon_index) = colon_index {
+ if colon_index == 0 {
+ resource_string = resource_string.split_off(1);
}
+ NonZeroUsize::new(colon_index)
} else {
- (DEFAULT_NAMESPACE, resource_string)
+ None
};
- Identifier {
- namespace: namespace.to_string(),
- path: path.to_string(),
+
+ Self {
+ colon_index,
+ inner: resource_string.into(),
+ }
+ }
+
+ pub fn namespace(&self) -> &str {
+ if let Some(colon_index) = self.colon_index {
+ &self.inner[0..colon_index.get()]
+ } else {
+ DEFAULT_NAMESPACE
+ }
+ }
+ pub fn path(&self) -> &str {
+ if let Some(colon_index) = self.colon_index {
+ &self.inner[(colon_index.get() + 1)..]
+ } else {
+ &self.inner
}
}
}
-impl fmt::Display for Identifier {
+impl Display for Identifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}:{}", self.namespace, self.path)
+ if self.colon_index.is_some() {
+ write!(f, "{}", self.inner)
+ } else {
+ write!(f, "{DEFAULT_NAMESPACE}:{}", self.inner)
+ }
}
}
-impl fmt::Debug for Identifier {
+impl Debug for Identifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}:{}", self.namespace, self.path)
+ write!(f, "{self}")
}
}
impl FromStr for Identifier {
@@ -125,26 +145,26 @@ mod tests {
#[test]
fn basic_identifier() {
let r = Identifier::new("abcdef:ghijkl");
- assert_eq!(r.namespace, "abcdef");
- assert_eq!(r.path, "ghijkl");
+ assert_eq!(r.namespace(), "abcdef");
+ assert_eq!(r.path(), "ghijkl");
}
#[test]
fn no_namespace() {
let r = Identifier::new("azalea");
- assert_eq!(r.namespace, "minecraft");
- assert_eq!(r.path, "azalea");
+ assert_eq!(r.namespace(), "minecraft");
+ assert_eq!(r.path(), "azalea");
}
#[test]
fn colon_start() {
let r = Identifier::new(":azalea");
- assert_eq!(r.namespace, "minecraft");
- assert_eq!(r.path, "azalea");
+ assert_eq!(r.namespace(), "minecraft");
+ assert_eq!(r.path(), "azalea");
}
#[test]
fn colon_end() {
let r = Identifier::new("azalea:");
- assert_eq!(r.namespace, "azalea");
- assert_eq!(r.path, "");
+ assert_eq!(r.namespace(), "azalea");
+ assert_eq!(r.path(), "");
}
#[test]