diff --git a/src/fomod.rs b/src/fomod.rs index 419d790..3dad4b7 100644 --- a/src/fomod.rs +++ b/src/fomod.rs @@ -4,6 +4,7 @@ use std::{fs, io, path::Path}; +use log::debug; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -55,6 +56,11 @@ pub struct Config { impl Config { pub fn load_from_file(path: impl AsRef) -> Result { + debug!( + "Loading FOmod config from {}", + path.as_ref().to_string_lossy() + ); + let data = fs::read_to_string(path)?; let config = quick_xml::de::from_str(&data)?; @@ -142,7 +148,7 @@ pub struct InstallStep { #[serde(rename = "@name")] pub name: String, - pub visible: Option, + pub visible: Option, #[serde(rename = "optionalFileGroups")] pub optional_file_groups: GroupList, @@ -151,6 +157,7 @@ pub struct InstallStep { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ModuleDependency { #[serde(rename = "@operator")] + #[serde(default)] pub operator: DependencyOperator, #[serde(rename = "$value")] pub list: Vec, @@ -207,8 +214,11 @@ pub enum DependencyState { Missing, } -#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive( + Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, +)] pub enum DependencyOperator { + #[default] And, Or, } diff --git a/src/mod_config_installer.rs b/src/mod_config_installer.rs index 3eddf38..c82037a 100644 --- a/src/mod_config_installer.rs +++ b/src/mod_config_installer.rs @@ -4,7 +4,7 @@ use log::{debug, warn}; use crate::fomod::{ CompositeDependency, Config, DependencyOperator, DependencyState, FileList, FileTypeEnum, - Group, GroupType, Plugin, PluginTypeDescriptorEnum, PluginTypeEnum, + Group, GroupType, ModuleDependency, Plugin, PluginTypeDescriptorEnum, PluginTypeEnum, }; #[derive(Debug)] @@ -101,6 +101,22 @@ fn evaluate_dependency( } } +fn evaluate_module_depbendecy( + dep: &ModuleDependency, + state: &InstallerState, + installed_plugins: &[String], +) -> bool { + let mut evaluated = dep + .list + .iter() + .map(|e| evaluate_dependency(e, state, installed_plugins)); + + match dep.operator { + DependencyOperator::And => evaluated.all(|r| r), + DependencyOperator::Or => evaluated.any(|r| r), + } +} + pub struct GroupPrompt { pub name: String, pub select_type: GroupType, @@ -191,7 +207,7 @@ pub fn run_fomod_installer( if step .visible .as_ref() - .is_some_and(|v| !evaluate_dependency(v, &state, installed_plugins)) + .is_some_and(|v| !evaluate_module_depbendecy(v, &state, installed_plugins)) { // Dependency to show the step not meet. Skipping. continue;