From 7e20cd370cc791ed9de0ffd7d007dccfdba3d5fe Mon Sep 17 00:00:00 2001 From: Niklas Kapelle Date: Sun, 29 Mar 2026 22:48:21 +0200 Subject: [PATCH] removed callback function from fomod installer --- src/actions/install.rs | 10 ++++- src/mod_config_installer.rs | 88 +++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/actions/install.rs b/src/actions/install.rs index 2c7fe85..ede7586 100644 --- a/src/actions/install.rs +++ b/src/actions/install.rs @@ -8,7 +8,7 @@ use log::{debug, trace}; use crate::{ fomod, install_prompt, - mod_config_installer::run_fomod_installer, + mod_config_installer::FomodInstaller, types::{ModConfig, ModFile, ModdedInstance, RootConfig}, utils::{resolve_case_insensitive, walk_all_files}, }; @@ -66,7 +66,13 @@ fn install_fomod( .collect(); trace!("Current loded plugins: {:?}", active_plugins); - let files = run_fomod_installer(module_config, &active_plugins, install_prompt::prompt)?; + + let mut installer = FomodInstaller::new(&module_config, &active_plugins); + let mut selection: Option> = None; + while let Some(prompt) = installer.run_step(selection.as_deref()) { + selection = Some(install_prompt::prompt(prompt)); + } + let files = installer.finalize(); let mod_files: Vec<_> = files .iter() diff --git a/src/mod_config_installer.rs b/src/mod_config_installer.rs index 40d7f6e..ec1af4f 100644 --- a/src/mod_config_installer.rs +++ b/src/mod_config_installer.rs @@ -191,66 +191,80 @@ fn resolve_plugin_type( } } -pub fn run_fomod_installer( - fomod_config: Config, - installed_plugins: &[String], - group_prompt: fn(GroupPrompt) -> Vec, -) -> anyhow::Result> { - let mut state = InstallerState::new(); +pub struct FomodInstaller<'a> { + state: InstallerState, + current_step: (usize, usize), + config: &'a Config, + installed_plugins: &'a [String], +} - // Always-installed files first - if let Some(required) = &fomod_config.required_install_files { - state.add_files(required); +impl<'a> FomodInstaller<'a> { + pub fn new(fomod_config: &'a Config, installed_plugins: &'a [String]) -> Self { + let mut state = InstallerState::new(); + if let Some(required) = &fomod_config.required_install_files { + state.add_files(required); + } + + Self { + state, + current_step: (0, 0), + config: fomod_config, + installed_plugins, + } } - if let Some(install_steps) = fomod_config.install_steps { - let steps = &install_steps.install_step; + pub fn run_step(&mut self, selection: Option<&[usize]>) -> Option { + let Some(install_steps) = &self.config.install_steps else { + return None; + }; - for step in steps { - // Check if the step should be visible - if step - .visible - .as_ref() - .is_some_and(|v| !evaluate_module_depbendecy(v, &state, installed_plugins)) - { - // Dependency to show the step not meet. Skipping. - continue; - } + let step = install_steps.install_step.get(self.current_step.0)?; - for group in &step.optional_file_groups.group { - // TODO: Skip groups where all plugins are NotUsable + // Check if the step should be visible + if step + .visible + .as_ref() + .is_some_and(|v| !evaluate_module_depbendecy(v, &self.state, self.installed_plugins)) + { + // Dependency to show the step not meet. Skipping. + self.current_step = (self.current_step.0 + 1, 0); + return self.run_step(selection); + } - let prompt = GroupPrompt::new(group, &state, installed_plugins); + let Some(group) = step.optional_file_groups.group.get(self.current_step.1) else { + self.current_step = (self.current_step.0 + 1, 0); + return self.run_step(selection); + }; - let selected_plugins = (group_prompt)(prompt); + // TODO: Skip groups where all plugins are NotUsable + match selection { + Some(selected_plugins) => { for i in selected_plugins { - let plugin = &group.plugins.plugin[i]; + let plugin = &group.plugins.plugin[*i]; // Add files from selected plugin if let Some(files) = &plugin.files { - state.add_files(files); + self.state.add_files(files); } // Set condition flags if let Some(condition_flags) = &plugin.condition_flags { for flag in &condition_flags.flag { - state.set_flag(&flag.name, &flag.flag_value); + self.state.set_flag(&flag.name, &flag.flag_value); } } } + + // Next step + self.current_step = (self.current_step.0, self.current_step.1 + 1); + self.run_step(None) } + None => Some(GroupPrompt::new(group, &self.state, self.installed_plugins)), } } - // Evaluate conditional file installs based on final flag state - if let Some(conditional) = &fomod_config.conditional_file_installs { - for pattern in &conditional.patterns.pattern { - if evaluate_module_depbendecy(&pattern.dependencies, &state, installed_plugins) { - state.add_files(&pattern.files); - } - } + pub fn finalize(self) -> Vec { + self.state.into_file_list() } - - Ok(state.into_file_list()) }