1use std::path::PathBuf;
2
3#[derive(Default)]
4pub struct ModLoadOrder {
5 pub mod_list: ModList,
6}
7
8impl ModLoadOrder {
9 pub fn change_order_by_index(&mut self, from: usize, to: usize) {
10 if from >= self.mod_list.mods.len() || to >= self.mod_list.mods.len() {
11 return;
12 }
13 self.mod_list.mods.swap(from, to);
14 }
15
16 pub fn change_order_by_name(&mut self, from: &str, to: &str) {
17 let from_index = self.mod_list.mods.iter().position(|x| x.name == from);
18 let to_index = self.mod_list.mods.iter().position(|x| x.name == to);
19 if from_index.is_none() || to_index.is_none() {
20 return;
21 }
22 self.change_order_by_index(from_index.unwrap(), to_index.unwrap());
23 }
24}
25
26#[derive(Default)]
27pub struct ModList {
28 pub mods: Vec<Mod>,
29}
30
31impl ModList {
32 pub fn add_mod(&mut self, mod_: Mod) {
33 self.mods.push(mod_);
34 }
35
36 pub fn add_mod_from_path(&mut self, path: &PathBuf) -> std::io::Result<()> {
37 let mod_ = Mod::new_from_path(path)?;
38 self.add_mod(mod_);
39 Ok(())
40 }
41
42 pub fn add_mods_from_dir(&mut self, dir: &PathBuf) -> std::io::Result<()> {
43 let mut entries = std::fs::read_dir(dir)?
44 .map(|res| res.map(|e| e.path()))
45 .collect::<Result<Vec<_>, std::io::Error>>()?;
46
47 entries.sort();
48
49 for entry in entries {
50 let as_path = entry.as_path();
51 if as_path.is_file() {
52 self.add_mod_from_path(&entry.to_path_buf())?;
53 }
54 }
55 Ok(())
56 }
57}
58
59#[derive(Default)]
60pub struct Mod {
61 pub name: String,
62 pub path: String,
63 pub version: String,
64 pub remote_file_id: String,
65 pub supported_version: String,
66}
67
68impl Mod {
69 pub fn new_from_path(path: &PathBuf) -> std::io::Result<Mod> {
70 let content = std::fs::read_to_string(path)?;
71 Ok(Mod::new_from_file_content(&content))
72 }
73
74 fn new_from_file_content(content: &str) -> Mod {
75 mod_from_file_content(content)
76 }
77}
78pub fn mod_from_file_content(content: &str) -> Mod {
79 let mut mod_ = Mod::default();
80
81 for line in content.lines() {
82 let mut parts = line.split('=');
83 let key = parts.next().unwrap_or("");
84 let value = parts.next().unwrap_or("").trim_matches('"');
85
86 match key {
87 "name" => value.clone_into(&mut mod_.name),
88 "path" => value.clone_into(&mut mod_.path),
89 "version" => value.clone_into(&mut mod_.version),
90 "supported_version" => value.clone_into(&mut mod_.supported_version),
91 "remote_file_id" => value.clone_into(&mut mod_.remote_file_id),
92 _ => (),
93 }
94 }
95
96 mod_
97}