wot_game_reader 0.1.0

Fetch and extract data from the game folder of world of tanks
Documentation
use crate::errors::GameReadError;
use crate::game_reader::GameReader;
use serde::Serialize;
use serde_variant::to_variant_name;
use std::fs::File;
use std::path::PathBuf;
use poreader::PoParser;

pub struct LocalizationReader {
    game_reader: GameReader,
}

impl From<&GameReader> for LocalizationReader {
    fn from(game_reader: &GameReader) -> Self {
        LocalizationReader {
            game_reader: game_reader.clone(),
        }
    }
}

#[derive(Serialize)]
pub enum Nation {
    Multinational,
    Gb,
    Germany,
    Poland,
    Italy,
    Sweden,
    Ussr,
    Japan,
    Igr,
    China,
    Czech,
    France,
    Usa,
}

pub enum LocalizationCatalog {
    Arenas,
    Nations,
    Tanks(Nation),
}

impl LocalizationCatalog {
    pub fn get(&self, game_reader: &GameReader) -> Result<File, GameReadError> {
        let path = match self {
            LocalizationCatalog::Arenas => ["res", "text", "lc_messages", "arenas.po"]
                .iter()
                .collect::<PathBuf>(),
            LocalizationCatalog::Nations => ["res", "text", "lc_messages", "nations.po"]
                .iter()
                .collect::<PathBuf>(),
            LocalizationCatalog::Tanks(nation) => [
                "res",
                "text",
                "lc_messages",
                &format!("{}_vehicles.po", to_variant_name(nation)?),
            ]
            .iter()
            .collect::<PathBuf>(),
        };
        let filepath = game_reader.sources_path().join(path);
        Ok(File::open(filepath)?)
    }
}

impl LocalizationReader {
    pub fn fetch(&self, catalog: LocalizationCatalog, key: &str) -> Result<String, GameReadError> {
        let file = catalog.get(&self.game_reader)?;
        let parser = PoParser::new();
        let mut reader = parser.parse(file)?;
        let found = reader.find_map(|e| {
            match e {
                Ok(unit) => {
                    if unit.message().get_id() == key {
                        Some(unit.message().get_text().to_string())
                    } else {
                        None
                    }
                },
                _ => None,
            }
        });
        found.ok_or(GameReadError::LocalizationKeyNotFound)
    }
}