diff --git a/src/conflict_resolver.rs b/src/conflict_resolver.rs new file mode 100644 index 0000000..9fbe7bd --- /dev/null +++ b/src/conflict_resolver.rs @@ -0,0 +1,70 @@ +use std::{collections::HashMap, path::PathBuf}; + +use crate::{Mod, ModFile}; + +pub struct ConflictSolver<'a> { + files: HashMap, +} + +#[derive(Debug)] +pub struct Conflict<'a> { + rhs_mod: &'a Mod, + lhs_mod: &'a Mod, + rhs_file: &'a ModFile, + lhs_file: &'a ModFile, +} + +impl<'a> ConflictSolver<'a> { + pub fn new() -> Self { + Self { + files: HashMap::new(), + } + } + + pub fn add_file(&mut self, file: &'a ModFile, from_mod: &'a Mod) -> Option> { + let path = &file.dest; + match self.files.get(path) { + Some((current_file, current_file_mod)) => { + if from_mod == *current_file_mod { + // File from the same mod + // Check internal priority + if file.internal_priority > current_file.internal_priority { + self.files.insert(path.to_owned(), (file, from_mod)); + return None; + } + + if file.internal_priority == current_file.internal_priority { + // Same prio. We got a conflict. + + return Some(Conflict { + rhs_mod: from_mod, + lhs_mod: current_file_mod, + rhs_file: file, + lhs_file: current_file, + }); + } + } + + if from_mod.priority > current_file_mod.priority { + self.files.insert(path.to_owned(), (file, from_mod)); + return None; + } + + if from_mod.priority == current_file_mod.priority { + // Different mod but priority the same. We got a conflict. + return Some(Conflict { + rhs_mod: from_mod, + lhs_mod: current_file_mod, + rhs_file: file, + lhs_file: current_file, + }); + } + } + None => { + self.files.insert(path.to_owned(), (file, from_mod)); + } + } + + None + } +}