flatland_presentation/
validate.rs1use crate::{SpriteCatalog, SpriteModeMap};
4
5pub fn validate_sprite_mode_maps(
7 owner_label: &str,
8 tile_id: Option<&str>,
9 sprite_modes: &SpriteModeMap,
10 catalog: &SpriteCatalog,
11) -> Vec<String> {
12 let mut errors = Vec::new();
13 let Some(tile_id) = tile_id.filter(|s| !s.is_empty()) else {
14 if !sprite_modes.is_empty() {
15 errors.push(format!(
16 "{owner_label}: sprite_modes set but tile_id is missing"
17 ));
18 }
19 return errors;
20 };
21 if sprite_modes.is_empty() {
22 return errors;
23 }
24 let sheet_modes = catalog.mode_ids(tile_id);
25 if sheet_modes.is_empty() {
26 errors.push(format!(
27 "{owner_label}: tile_id '{tile_id}' not found in sprite catalog or has no modes"
28 ));
29 return errors;
30 }
31 for (key, mode) in sprite_modes {
32 if !mode_exists_on_sheet(mode, &sheet_modes) {
33 errors.push(format!(
34 "{owner_label}: sprite_modes.{key} = '{mode}' not on sheet '{tile_id}' (have: {})",
35 sheet_modes.join(", ")
36 ));
37 }
38 }
39 errors
40}
41
42pub fn mode_exists_on_sheet(mode: &str, sheet_modes: &[String]) -> bool {
44 if sheet_modes.iter().any(|m| m == mode) {
45 return true;
46 }
47 let prefix = format!("{mode}_");
48 sheet_modes.iter().any(|m| m.starts_with(&prefix))
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::catalog::{load_sprite_catalog, SpriteSheetModes};
55 use std::collections::HashMap;
56
57 #[test]
58 fn catches_unknown_mode() {
59 let dir = crate::catalog::default_sprites_dir().expect("sprites dir");
60 let catalog = load_sprite_catalog(&dir).expect("load");
61 let mut map = SpriteModeMap::new();
62 map.insert("available".into(), "bogus_mode_xyz".into());
63 let errs = validate_sprite_mode_maps("item.test", Some("resource.oak_log"), &map, &catalog);
64 assert_eq!(errs.len(), 1);
65 assert!(errs[0].contains("bogus_mode_xyz"));
66 }
67
68 #[test]
69 fn accepts_directional_prefix_for_base_mode() {
70 let sheet_modes = vec!["idle_north".into(), "walk_south".into(), "combat".into()];
71 assert!(mode_exists_on_sheet("idle", &sheet_modes));
72 assert!(mode_exists_on_sheet("walk", &sheet_modes));
73 assert!(mode_exists_on_sheet("combat", &sheet_modes));
74 assert!(!mode_exists_on_sheet("run", &sheet_modes));
75 }
76}