homm5_scaner/entity/
mod.rs

1pub mod hero;
2pub mod creature;
3pub mod art;
4pub mod spell;
5
6use std::collections::HashMap;
7use serde::{Serialize, Deserialize};
8use homm5_types::common::FileRef;
9use crate::pak::FileStructure;
10
11#[derive(Debug, Serialize, Deserialize)]
12#[allow(non_snake_case)]
13pub struct FileObject {
14    pub ID: String,
15    pub Obj: Option<FileRef>
16}
17
18#[derive(Debug, Serialize, Deserialize)]
19pub struct FileObjects {
20    #[serde(rename = "Item")]
21    pub objects: Vec<FileObject>
22}
23
24pub trait CollectFiles {
25    fn collect(&self, files: &HashMap<String, FileStructure>, collected_files: &mut Vec<(String, FileStructure)>);
26}
27
28pub trait Scan<T> {
29    fn scan(&mut self, file_key: &String, entity: &String, files: &HashMap<String, FileStructure>) -> Option<Box<dyn Output<ID = T>>>;
30    fn get_id(&self) -> Option<T>;
31}
32
33pub trait Output {
34    type ID;
35    fn to_lua(&self, id: Option<Self::ID>) -> String;
36    fn to_json(&self) -> String;
37}
38
39pub struct ScanProcessor<T> {
40    pub table_name: String,
41    pub output_file_name: String,
42    pub collector: Box<dyn CollectFiles>,
43    pub scaner: Box<dyn Scan<T>>
44}
45
46impl<T> ScanProcessor<T> {
47    pub fn new(table: String, output: String, collector: Box<dyn CollectFiles>, processor: Box<dyn Scan<T>>) -> Self {
48        ScanProcessor { 
49            table_name: table, 
50            output_file_name: output, 
51            collector: collector,
52            scaner: processor 
53        }
54    }
55}
56
57impl<T> ScanProcessor<T> {
58    pub fn run(&mut self, files: &HashMap<String, FileStructure>) -> (String, String) {
59        let mut actual_files = vec![];
60        self.collector.collect(files, &mut actual_files);
61        println!("files collected: {:?}", &actual_files);
62        let mut output_string = format!("{} = {{\n", &self.table_name);
63        let mut json_string = String::from("[");
64        for file in actual_files {
65            let scanned_file = self.scaner.scan(&file.0, &file.1.content, files);
66            let id = self.scaner.get_id();
67            match scanned_file {
68                Some(actual_file) => {
69                    output_string += &actual_file.to_lua(id);
70                    json_string += &format!("{},\n", actual_file.to_json());
71                },
72                None => {}
73            }
74        }
75        output_string.trim_end_matches(",").to_string();
76        output_string.push('}');
77        json_string = json_string.trim_end_matches(",").to_owned();
78        (output_string, json_string)
79    }
80}
81
82pub fn configure_path(path: Option<&String>, file_key: &String, files: &HashMap<String, FileStructure>) -> String {
83    match path {
84        Some(actual_path) => {
85            let actual_path = actual_path.trim_start_matches("/").to_lowercase();
86            println!("actual path is {}", &actual_path);
87            if files.contains_key(&actual_path) == false {
88                println!("and it not in files");
89                let actual_name = file_key.rsplit_once("/").unwrap().0.to_string() + &format!("/{}", &actual_path);
90                //println!("name was {}, key {}, actual name {}", actual_path, file_key, &actual_name);
91                actual_name
92            }
93            else {
94                actual_path
95            }
96        }
97        None => {
98            String::new()
99        }
100    }
101}