1use std::sync::LazyLock;
5
6#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
8pub struct Atlas {
9 pub id: String,
11 pub description: String,
12 pub since: Option<String>,
14 #[data(default)]
16 pub dirs: Vec<String>,
17 #[data(default)]
19 pub bare: bool,
20}
21
22static ATLASES: LazyLock<Vec<Atlas>> = LazyLock::new(|| {
23 yog_data::from_text::<Vec<Atlas>>(include_str!("../assets/atlases.ydata"))
24 .unwrap_or_else(|e| panic!("yog-registry's atlases: {e}"))
25 .value
26});
27
28impl Atlas {
29 pub fn game() -> &'static [Atlas] {
31 &ATLASES
32 }
33
34 pub fn of_path(path: &str) -> Option<&'static Atlas> {
36 ATLASES.iter().find(|a| a.dir_of(path).is_some())
37 }
38
39 fn dir_of<'p>(&self, path: &'p str) -> Option<&'p str> {
41 self.dirs.iter().find_map(|d| path.strip_prefix(d.as_str())?.strip_prefix(yog_ids::sep::PATH))
42 }
43
44 pub fn sprite<'p>(&self, path: &'p str) -> &'p str {
47 if self.bare { self.dir_of(path).unwrap_or(path) } else { path }
48 }
49
50 pub fn find(id: &str) -> Option<&'static Atlas> {
52 let id = yog_ids::qualify(id);
53 ATLASES.iter().find(|a| a.id == id)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 #[test]
60 fn the_games_atlases_read() {
61 assert!(super::Atlas::find("blocks").is_some());
62 assert_eq!(super::Atlas::find("minecraft:gui").and_then(|a| a.since.as_deref()), Some("1.20.2"));
63 assert_eq!(super::Atlas::of_path("item/staff/oak").map(|a| a.id.as_str()), Some("minecraft:blocks"));
64 assert!(super::Atlas::of_path("entity/wisp").is_none());
65 let effects = super::Atlas::of_path("mob_effect/clarity").unwrap();
66 assert_eq!(effects.sprite("mob_effect/clarity"), "clarity");
67 assert_eq!(super::Atlas::find("blocks").unwrap().sprite("block/ruby"), "block/ruby");
68 assert_eq!(super::Atlas::of_path("gui/sprites/hud/x").map(|a| a.id.as_str()), Some("minecraft:gui"));
69 }
70}