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}