Skip to main content

conduit_cli/core/engine/io/
mrpack.rs

1use std::{collections::HashMap, fs::File, path::PathBuf};
2
3use crate::{
4    core::{engine::archive::SafeArchive, schemas::modpacks::modrinth::ModrinthIndex},
5    errors::{ConduitError, ConduitResult},
6};
7
8pub struct MrPackManager {
9    pub file: ModrinthIndex,
10}
11
12impl MrPackManager {
13    pub fn new(
14        path: &PathBuf,
15        index: ModrinthIndex,
16        extra_files: HashMap<String, Vec<u8>>,
17        overrides: Option<(PathBuf, Vec<PathBuf>)>,
18    ) -> ConduitResult<Self> {
19        let mut writer = SafeArchive::create(path)?;
20
21        SafeArchive::serialize_and_add(&mut writer, "modrinth.index.json", &index)?;
22
23        for (name, content) in extra_files {
24            SafeArchive::add_file(&mut writer, &name, &content)?;
25        }
26
27        if let Some((root, files)) = overrides {
28            for file_path in files {
29                if file_path.is_file() {
30                    let relative = file_path.strip_prefix(&root).map_err(|_| {
31                        ConduitError::Storage(
32                            "Failed to strip prefix for mrpack override".to_string(),
33                        )
34                    })?;
35
36                    let zip_path = format!(
37                        "overrides/{}",
38                        relative.to_string_lossy().replace('\\', "/")
39                    );
40
41                    let file = File::open(&file_path)?;
42                    SafeArchive::add_file_from_reader(&mut writer, &zip_path, file)?;
43                }
44            }
45        }
46
47        writer
48            .finish()
49            .map_err(|e| ConduitError::Storage(format!("Failed to finalize mrpack: {e}")))?;
50
51        Ok(Self { file: index })
52    }
53
54    pub fn open(path: PathBuf) -> ConduitResult<Self> {
55        let mut zip = SafeArchive::open(path)?;
56
57        let file: ModrinthIndex =
58            SafeArchive::read_and_deserialize(&mut zip, "modrinth.index.json")?;
59
60        Ok(MrPackManager { file })
61    }
62}