minecraft_assets/api/resource/model_identifier.rs
1/// Helper methods for dealing with model identifiers.
2///
3/// # Why does this exist?
4///
5/// Prior to 1.13, model identifiers found in
6/// `assets/<namespace>/blockstates/*.json` did not include a prefix like
7/// `block/` or `item/` to disambiguate between different types of models.
8///
9/// Because of this, the `minecraft-assets` API forces the user to always
10/// specify which type of model they are trying to reference (note the existence
11/// of both [`BlockModel`] and [`ItemModel`] variants in [`ResourceKind`]). This
12/// way, the API will work with versions prior to 1.13.
13///
14/// So this struct is meant to wrap an identifier and extract its model name.
15/// See the [`model_name()`] documentation for more information.
16///
17/// [`ResourceKind`]: crate::api::ResourceKind
18/// [`BlockModel`]: crate::api::ResourceKind::BlockModel
19/// [`ItemModel`]: crate::api::ResourceKind::ItemModel
20/// [`model_name()`]: Self::model_name
21#[derive(Debug, Clone, Hash)]
22pub struct ModelIdentifier;
23
24impl ModelIdentifier {
25 /// Returns the name of the model, stripping the leading path component if
26 /// there is one.
27 ///
28 /// # Example
29 ///
30 /// ```
31 /// # use minecraft_assets::api::*;
32 /// assert_eq!(ModelIdentifier::model_name("stone"), "stone");
33 /// assert_eq!(ModelIdentifier::model_name("block/oak_planks"), "oak_planks");
34 /// assert_eq!(ModelIdentifier::model_name("item/diamond_hoe"), "diamond_hoe");
35 /// ```
36 pub fn model_name(id: &str) -> &str {
37 Self::slash_position(id)
38 .map(|index| &id[index + 1..])
39 .unwrap_or_else(|| id)
40 }
41
42 pub(crate) fn is_builtin(id: &str) -> bool {
43 match Self::slash_position(id) {
44 Some(index) => {
45 let prefix = &id[..index];
46 prefix == "builtin"
47 }
48 None => false,
49 }
50 }
51
52 fn slash_position(id: &str) -> Option<usize> {
53 id.chars().position(|c| c == '/')
54 }
55}