mirror of
https://github.com/loot/loot-condition-interpreter.git
synced 2026-07-27 14:16:09 -07:00
Add evaluation of active() and many_active() conditions
This commit is contained in:
@@ -92,6 +92,32 @@ fn evaluate_many(state: &State, parent_path: &Path, regex: &Regex) -> Result<boo
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn evaluate_active_path(state: &State, path: &Path) -> Result<bool, Error> {
|
||||||
|
Ok(path
|
||||||
|
.to_str()
|
||||||
|
.map(|s| state.active_plugins.contains(&s.to_lowercase()))
|
||||||
|
.unwrap_or(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evaluate_active_regex(state: &State, regex: &Regex) -> Result<bool, Error> {
|
||||||
|
Ok(state.active_plugins.iter().any(|p| regex.is_match(p)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evaluate_many_active(state: &State, regex: &Regex) -> Result<bool, Error> {
|
||||||
|
let mut found_one = false;
|
||||||
|
for active_plugin in &state.active_plugins {
|
||||||
|
if regex.is_match(&active_plugin) {
|
||||||
|
if found_one {
|
||||||
|
return Ok(true);
|
||||||
|
} else {
|
||||||
|
found_one = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn eval(&self, state: &State) -> Result<bool, Error> {
|
pub fn eval(&self, state: &State) -> Result<bool, Error> {
|
||||||
// TODO: Handle all variants.
|
// TODO: Handle all variants.
|
||||||
@@ -99,7 +125,10 @@ impl Function {
|
|||||||
match *self {
|
match *self {
|
||||||
Function::FilePath(ref f) => evaluate_file_path(state, f),
|
Function::FilePath(ref f) => evaluate_file_path(state, f),
|
||||||
Function::FileRegex(ref p, ref r) => evaluate_file_regex(state, p, r),
|
Function::FileRegex(ref p, ref r) => evaluate_file_regex(state, p, r),
|
||||||
|
Function::ActivePath(ref p) => evaluate_active_path(state, p),
|
||||||
|
Function::ActiveRegex(ref r) => evaluate_active_regex(state, r),
|
||||||
Function::Many(ref p, ref r) => evaluate_many(state, p, r),
|
Function::Many(ref p, ref r) => evaluate_many(state, p, r),
|
||||||
|
Function::ManyActive(ref r) => evaluate_many_active(state, r),
|
||||||
_ => Ok(false),
|
_ => Ok(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,6 +146,10 @@ mod tests {
|
|||||||
use GameType;
|
use GameType;
|
||||||
|
|
||||||
fn state<T: Into<PathBuf>>(data_path: T) -> State {
|
fn state<T: Into<PathBuf>>(data_path: T) -> State {
|
||||||
|
state_with_active_plugins(data_path, &[])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state_with_active_plugins<T: Into<PathBuf>>(data_path: T, active_plugins: &[&str]) -> State {
|
||||||
let data_path = data_path.into();
|
let data_path = data_path.into();
|
||||||
if !data_path.exists() {
|
if !data_path.exists() {
|
||||||
create_dir(&data_path).unwrap();
|
create_dir(&data_path).unwrap();
|
||||||
@@ -125,6 +158,10 @@ mod tests {
|
|||||||
State {
|
State {
|
||||||
game_type: GameType::tes4,
|
game_type: GameType::tes4,
|
||||||
data_path: data_path,
|
data_path: data_path,
|
||||||
|
active_plugins: active_plugins
|
||||||
|
.into_iter()
|
||||||
|
.map(|s| s.to_lowercase())
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +256,46 @@ mod tests {
|
|||||||
assert!(function.eval(&state).unwrap());
|
assert!(function.eval(&state).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_active_path_eval_should_be_true_if_the_path_is_an_active_plugin() {
|
||||||
|
let function = Function::ActivePath(PathBuf::from("Blank.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp"]);
|
||||||
|
|
||||||
|
assert!(function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_active_path_eval_should_be_case_insensitive() {
|
||||||
|
let function = Function::ActivePath(PathBuf::from("Blank.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["blank.esp"]);
|
||||||
|
|
||||||
|
assert!(function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_active_path_eval_should_be_false_if_the_path_is_not_an_active_plugin() {
|
||||||
|
let function = Function::ActivePath(PathBuf::from("inactive.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp"]);
|
||||||
|
|
||||||
|
assert!(!function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_active_regex_eval_should_be_true_if_the_regex_matches_an_active_plugin() {
|
||||||
|
let function = Function::ActiveRegex(regex("Blank\\.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp"]);
|
||||||
|
|
||||||
|
assert!(function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_active_regex_eval_should_be_false_if_the_regex_does_not_match_an_active_plugin() {
|
||||||
|
let function = Function::ActiveRegex(regex("inactive\\.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp"]);
|
||||||
|
|
||||||
|
assert!(!function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_many_eval_should_be_false_if_no_directory_entries_match() {
|
fn function_many_eval_should_be_false_if_no_directory_entries_match() {
|
||||||
let function = Function::Many(PathBuf::from("."), regex("missing"));
|
let function = Function::Many(PathBuf::from("."), regex("missing"));
|
||||||
@@ -256,4 +333,28 @@ mod tests {
|
|||||||
|
|
||||||
assert!(function.eval(&state).unwrap());
|
assert!(function.eval(&state).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_many_active_eval_should_be_true_if_the_regex_matches_more_than_one_active_plugin() {
|
||||||
|
let function = Function::ManyActive(regex("Blank.*"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp", "Blank.esm"]);
|
||||||
|
|
||||||
|
assert!(function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_many_active_eval_should_be_false_if_one_active_plugin_matches() {
|
||||||
|
let function = Function::ManyActive(regex("Blank\\.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp", "Blank.esm"]);
|
||||||
|
|
||||||
|
assert!(!function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_many_active_eval_should_be_false_if_the_regex_does_not_match_an_active_plugin() {
|
||||||
|
let function = Function::ManyActive(regex("inactive\\.esp"));
|
||||||
|
let state = state_with_active_plugins(".", &["Blank.esp", "Blank.esm"]);
|
||||||
|
|
||||||
|
assert!(!function.eval(&state).unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ extern crate regex;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate tempfile;
|
extern crate tempfile;
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str;
|
use std::str;
|
||||||
@@ -61,6 +62,7 @@ impl GameType {
|
|||||||
pub struct State {
|
pub struct State {
|
||||||
game_type: GameType,
|
game_type: GameType,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
|
active_plugins: HashSet<String>, // Lowercased plugin filenames.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compound conditions joined by 'or'
|
// Compound conditions joined by 'or'
|
||||||
@@ -160,6 +162,7 @@ mod tests {
|
|||||||
State {
|
State {
|
||||||
game_type: GameType::tes4,
|
game_type: GameType::tes4,
|
||||||
data_path: data_path,
|
data_path: data_path,
|
||||||
|
active_plugins: HashSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user