flatland_presentation/
player_config.rs1use std::path::Path;
4
5use serde::Deserialize;
6
7use crate::SpriteModeMap;
8
9#[derive(Debug, Clone, Default, Deserialize)]
10pub struct PlayerPresentationDoc {
11 #[serde(default)]
12 pub player_presentation: PlayerPresentationConfig,
13}
14
15#[derive(Debug, Clone, Default, Deserialize)]
16pub struct PlayerPresentationConfig {
17 #[serde(default)]
18 pub tile_id: Option<String>,
19 #[serde(default)]
20 pub sprite_modes: SpriteModeMap,
21}
22
23impl PlayerPresentationConfig {
24 pub fn empty() -> Self {
25 Self::default()
26 }
27}
28
29pub fn default_player_presentation_path() -> Option<std::path::PathBuf> {
30 let mut dir = std::env::current_dir().ok()?;
31 for _ in 0..6 {
32 let candidate = dir.join("assets/gfx/player-presentation.yaml");
33 if candidate.is_file() {
34 return Some(candidate);
35 }
36 if !dir.pop() {
37 break;
38 }
39 }
40 None
41}
42
43pub fn load_player_presentation(
44 path: impl AsRef<Path>,
45) -> anyhow::Result<PlayerPresentationConfig> {
46 let raw = std::fs::read_to_string(path.as_ref())?;
47 let doc: PlayerPresentationDoc = serde_yaml::from_str(&raw)?;
48 Ok(doc.player_presentation)
49}
50
51pub fn load_player_presentation_default() -> PlayerPresentationConfig {
52 default_player_presentation_path()
53 .and_then(|p| load_player_presentation(&p).ok())
54 .unwrap_or_default()
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn loads_repo_default() {
63 let path = default_player_presentation_path().expect("player-presentation.yaml");
64 let cfg = load_player_presentation(&path).expect("parse");
65 assert!(cfg.tile_id.is_some() || !cfg.sprite_modes.is_empty());
66 }
67}