homm5_scaner/entity/
mod.rs1pub 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 actual_name
92 }
93 else {
94 actual_path
95 }
96 }
97 None => {
98 String::new()
99 }
100 }
101}