tiger_lib/
mod_metadata.rs

1//! Loader and validator for the `.metadata/metadata.json` files used by Vic3
2
3use std::path::{Path, PathBuf};
4
5use anyhow::{Context, Result};
6
7use crate::block::Block;
8use crate::fileset::{FileEntry, FileKind, FileStage};
9use crate::parse::json::parse_json_file;
10use crate::token::Token;
11use crate::util::fix_slashes_for_target_platform;
12
13/// Representation of a `metadata.json` file and its contents.
14#[derive(Clone, Debug)]
15pub struct ModMetadata {
16    /// Path to the mod itself
17    modpath: PathBuf,
18    /// Parsed version of the json file
19    block: Block,
20}
21
22impl ModMetadata {
23    /// Read and parse the metadata file for the given mod dir
24    pub fn read(mod_dir: &Path) -> Result<Self> {
25        let in_mod_path = PathBuf::from(".metadata/metadata.json");
26        let pathname = fix_slashes_for_target_platform(mod_dir.join(&in_mod_path));
27        let entry =
28            FileEntry::new(in_mod_path, FileStage::NoStage, FileKind::Mod, pathname.clone());
29        let block = parse_json_file(&entry)
30            .with_context(|| format!("could not read metadata file {}", pathname.display()))?;
31        Ok(Self { modpath: mod_dir.to_path_buf(), block })
32    }
33
34    /// Return the full path to the mod root.
35    pub fn modpath(&self) -> &Path {
36        &self.modpath
37    }
38
39    /// Return the paths that this mod fully replaces
40    pub fn replace_paths(&self) -> Vec<PathBuf> {
41        if let Some(custom_data) = self.block.get_field_block("game_custom_data") {
42            if let Some(replace_paths) = custom_data.get_field_list("replace_paths") {
43                return replace_paths.iter().map(|t| PathBuf::from(t.as_str())).collect();
44            }
45        }
46        Vec::new()
47    }
48
49    /// The mod's name in human-friendly form, if available.
50    pub fn display_name(&self) -> Option<&'static str> {
51        self.block.get_field_value("name").map(Token::as_str)
52    }
53}