mirror of
https://github.com/loot/loot-condition-interpreter.git
synced 2026-07-27 14:16:09 -07:00
Implement Display trait on Expression and all types it depends on
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -16,6 +17,20 @@ pub enum ComparisonOperator {
|
|||||||
GreaterThanOrEqual,
|
GreaterThanOrEqual,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ComparisonOperator {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use self::ComparisonOperator::*;
|
||||||
|
match self {
|
||||||
|
Equal => write!(f, "=="),
|
||||||
|
NotEqual => write!(f, "=="),
|
||||||
|
LessThan => write!(f, "<"),
|
||||||
|
GreaterThan => write!(f, ">"),
|
||||||
|
LessThanOrEqual => write!(f, "<="),
|
||||||
|
GreaterThanOrEqual => write!(f, ">="),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Function {
|
pub enum Function {
|
||||||
FilePath(PathBuf),
|
FilePath(PathBuf),
|
||||||
@@ -28,6 +43,22 @@ pub enum Function {
|
|||||||
Version(PathBuf, String, ComparisonOperator),
|
Version(PathBuf, String, ComparisonOperator),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Function {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use Function::*;
|
||||||
|
match self {
|
||||||
|
FilePath(p) => write!(f, "file(\"{}\")", p.display()),
|
||||||
|
FileRegex(p, r) => write!(f, "file(\"{}/{}\")", p.display(), r),
|
||||||
|
ActivePath(p) => write!(f, "active(\"{}\")", p.display()),
|
||||||
|
ActiveRegex(r) => write!(f, "active(\"{}\")", r),
|
||||||
|
Many(p, r) => write!(f, "many(\"{}/{}\")", p.display(), r),
|
||||||
|
ManyActive(r) => write!(f, "many_active(\"{}\")", r),
|
||||||
|
Checksum(p, c) => write!(f, "checksum(\"{}\", {:02X?})", p.display(), c),
|
||||||
|
Version(p, v, c) => write!(f, "version(\"{}\", \"{}\", {})", p.display(), v, c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for Function {
|
impl PartialEq for Function {
|
||||||
fn eq(&self, other: &Function) -> bool {
|
fn eq(&self, other: &Function) -> bool {
|
||||||
use Function::*;
|
use Function::*;
|
||||||
@@ -63,6 +94,72 @@ mod tests {
|
|||||||
Regex::new(string).unwrap()
|
Regex::new(string).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_file_path_should_format_correctly() {
|
||||||
|
let function = Function::FilePath("subdir/Blank.esm".into());
|
||||||
|
|
||||||
|
assert_eq!("file(\"subdir/Blank.esm\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_file_regex_should_format_correctly() {
|
||||||
|
let function = Function::FileRegex("subdir".into(), regex("Blank.*"));
|
||||||
|
|
||||||
|
assert_eq!("file(\"subdir/Blank.*\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_active_path_should_format_correctly() {
|
||||||
|
let function = Function::ActivePath("Blank.esm".into());
|
||||||
|
|
||||||
|
assert_eq!("active(\"Blank.esm\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_active_regex_should_format_correctly() {
|
||||||
|
let function = Function::ActiveRegex(regex("Blank.*"));
|
||||||
|
|
||||||
|
assert_eq!("active(\"Blank.*\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_many_should_format_correctly() {
|
||||||
|
let function = Function::Many("subdir".into(), regex("Blank.*"));
|
||||||
|
|
||||||
|
assert_eq!("many(\"subdir/Blank.*\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_many_active_should_format_correctly() {
|
||||||
|
let function = Function::ManyActive(regex("Blank.*"));
|
||||||
|
|
||||||
|
assert_eq!("many_active(\"Blank.*\")", &format!("{}", function));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_checksum_should_format_correctly() {
|
||||||
|
let function = Function::Checksum("subdir/Blank.esm".into(), 0xDEADBEEF);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
"checksum(\"subdir/Blank.esm\", DEADBEEF)",
|
||||||
|
&format!("{}", function)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_fmt_for_version_should_format_correctly() {
|
||||||
|
let function = Function::Version(
|
||||||
|
"subdir/Blank.esm".into(),
|
||||||
|
"1.2a".into(),
|
||||||
|
ComparisonOperator::Equal,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
"version(\"subdir/Blank.esm\", \"1.2a\", ==)",
|
||||||
|
&format!("{}", function)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_eq_for_file_path_should_check_pathbuf() {
|
fn function_eq_for_file_path_should_check_pathbuf() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
+92
@@ -13,6 +13,7 @@ mod version;
|
|||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str;
|
use std::str;
|
||||||
@@ -116,6 +117,13 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Expression {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let strings: Vec<String> = self.0.iter().map(CompoundCondition::to_string).collect();
|
||||||
|
write!(f, "{}", strings.join(" or "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Conditions joined by 'and'
|
// Conditions joined by 'and'
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
struct CompoundCondition(Vec<Condition>);
|
struct CompoundCondition(Vec<Condition>);
|
||||||
@@ -139,6 +147,13 @@ impl CompoundCondition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CompoundCondition {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let strings: Vec<String> = self.0.iter().map(Condition::to_string).collect();
|
||||||
|
write!(f, "{}", strings.join(" and "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
enum Condition {
|
enum Condition {
|
||||||
Function(Function),
|
Function(Function),
|
||||||
@@ -174,6 +189,17 @@ impl Condition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Condition {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use Condition::*;
|
||||||
|
match self {
|
||||||
|
Function(function) => write!(f, "{}", function),
|
||||||
|
InvertedFunction(function) => write!(f, "not {}", function),
|
||||||
|
Expression(e) => write!(f, "({})", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -478,6 +504,30 @@ mod tests {
|
|||||||
assert!(condition.eval(&state).unwrap());
|
assert!(condition.eval(&state).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn condition_fmt_should_format_function_correctly() {
|
||||||
|
let condition = Condition::Function(Function::FilePath(PathBuf::from("Cargo.toml")));
|
||||||
|
|
||||||
|
assert_eq!("file(\"Cargo.toml\")", &format!("{}", condition));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn condition_fmt_should_format_inverted_function_correctly() {
|
||||||
|
let condition =
|
||||||
|
Condition::InvertedFunction(Function::FilePath(PathBuf::from("Cargo.toml")));
|
||||||
|
|
||||||
|
assert_eq!("not file(\"Cargo.toml\")", &format!("{}", condition));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn condition_fmt_should_format_expression_correctly() {
|
||||||
|
let condition = Condition::Expression(Expression(vec![CompoundCondition(vec![
|
||||||
|
Condition::Function(Function::FilePath(PathBuf::from("Cargo.toml"))),
|
||||||
|
])]));
|
||||||
|
|
||||||
|
assert_eq!("(file(\"Cargo.toml\"))", &format!("{}", condition));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compound_condition_eval_should_be_true_if_all_conditions_are_true() {
|
fn compound_condition_eval_should_be_true_if_all_conditions_are_true() {
|
||||||
let state = state(".");
|
let state = state(".");
|
||||||
@@ -502,6 +552,25 @@ mod tests {
|
|||||||
assert!(!compound_condition.eval(&state).unwrap());
|
assert!(!compound_condition.eval(&state).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compound_condition_fmt_should_format_correctly() {
|
||||||
|
let compound_condition = CompoundCondition(vec![
|
||||||
|
Condition::Function(Function::FilePath(PathBuf::from("Cargo.toml"))),
|
||||||
|
Condition::Function(Function::FilePath(PathBuf::from("missing"))),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
"file(\"Cargo.toml\") and file(\"missing\")",
|
||||||
|
&format!("{}", compound_condition)
|
||||||
|
);
|
||||||
|
|
||||||
|
let compound_condition = CompoundCondition(vec![Condition::Function(Function::FilePath(
|
||||||
|
PathBuf::from("Cargo.toml"),
|
||||||
|
))]);
|
||||||
|
|
||||||
|
assert_eq!("file(\"Cargo.toml\")", &format!("{}", compound_condition));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expression_eval_should_be_true_if_any_compound_condition_is_true() {
|
fn expression_eval_should_be_true_if_any_compound_condition_is_true() {
|
||||||
let state = state(".");
|
let state = state(".");
|
||||||
@@ -531,4 +600,27 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
assert!(!expression.eval(&state).unwrap());
|
assert!(!expression.eval(&state).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expression_fmt_should_format_correctly() {
|
||||||
|
let expression = Expression(vec![
|
||||||
|
CompoundCondition(vec![Condition::Function(Function::FilePath(
|
||||||
|
PathBuf::from("Cargo.toml"),
|
||||||
|
))]),
|
||||||
|
CompoundCondition(vec![Condition::Function(Function::FilePath(
|
||||||
|
PathBuf::from("missing"),
|
||||||
|
))]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
"file(\"Cargo.toml\") or file(\"missing\")",
|
||||||
|
&format!("{}", expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
let expression = Expression(vec![CompoundCondition(vec![Condition::Function(
|
||||||
|
Function::FilePath(PathBuf::from("Cargo.toml")),
|
||||||
|
)])]);
|
||||||
|
|
||||||
|
assert_eq!("file(\"Cargo.toml\")", &format!("{}", expression));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user