Skip to content

Commit

Permalink
continue refactor order
Browse files Browse the repository at this point in the history
  • Loading branch information
rfuzzo committed Dec 9, 2023
1 parent 08c82d0 commit ae6bda2
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 53 deletions.
50 changes: 31 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::BufRead;
Expand Down Expand Up @@ -73,23 +74,30 @@ pub fn topo_sort(
Ok(result)
}

pub fn parse_rules_from_dir<P>(rules_dir: P) -> io::Result<Vec<RuleKind>>
where
P: AsRef<Path>,
{
let rules_path = rules_dir.as_ref().join("cmop_rules_base.txt");
parse_rules(rules_path)
}

/// custom rules parser
///
/// # Errors
///
/// This function will return an error if .
pub fn parse_rules<P>(rules_dir: P) -> io::Result<Vec<RuleKind>>
pub fn parse_rules<P>(rules_path: P) -> io::Result<Vec<RuleKind>>
where
P: AsRef<Path>,
{
let mut rules: Vec<RuleKind> = vec![];

let mut order: Vec<(String, String)> = vec![];
// helpers for order rule
let mut orders: Vec<Vec<String>> = vec![];
let mut current_order: Vec<String> = vec![];

// todo scan directory for user files
let rules_path = rules_dir.as_ref().join("cmop_rules_base.txt");
let lines = read_lines(rules_path)?;
let mut parsing = false;
let mut current_rule: Option<RuleKind> = None;
Expand All @@ -106,13 +114,11 @@ where
if parsing && line.is_empty() {
parsing = false;
if let Some(rule) = current_rule.take() {
rules.push(rule);
// match rule {
// RuleKind::Order(o) => orders.push(current_order.to_owned()),
// RuleKind::Note(n) => rules.push(rule),
// RuleKind::Conflict(c) => rules.push(rule),
// RuleKind::Requires(r) => rules.push(rule),
// }
if let RuleKind::Order(_o) = rule {
orders.push(current_order.to_owned());
} else {
rules.push(rule);
}
} else {
// todo error
}
Expand Down Expand Up @@ -148,22 +154,22 @@ where
if parsing {
if let Some(current_rule) = &current_rule {
match current_rule {
RuleKind::Order(o) => {
RuleKind::Order(_o) => {
// order is just a list of names
current_order.push(line)
}
RuleKind::Note(n) => {
RuleKind::Note(_n) => {
// parse rule
// first line is the comment

// subsequent line is archive name

// handle more lines
}
RuleKind::Conflict(c) => {
RuleKind::Conflict(_c) => {
todo!()
}
RuleKind::Requires(r) => {
RuleKind::Requires(_r) => {
todo!()
}
}
Expand All @@ -172,15 +178,21 @@ where
}
orders.push(current_order.to_owned());

// process orders
// process order rules
for o in orders {
match o.len().cmp(&2) {
std::cmp::Ordering::Less => continue,
std::cmp::Ordering::Equal => order.push((o[0].to_owned(), o[1].to_owned())),
std::cmp::Ordering::Greater => {
Ordering::Less => continue,
Ordering::Equal => rules.push(RuleKind::Order(Order::new(
o[0].to_owned(),
o[1].to_owned(),
))),
Ordering::Greater => {
// add all pairs
for i in 0..o.len() - 1 {
order.push((o[i].to_owned(), o[i + 1].to_owned()));
rules.push(RuleKind::Order(Order::new(
o[i].to_owned(),
o[i + 1].to_owned(),
)));
}
}
}
Expand Down
16 changes: 2 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use clap::{Parser, Subcommand};
use cmop::rules::RuleKind;
use cmop::{gather_mods, get_mods_from_rules, parse_rules, read_file_as_list, topo_sort};
use std::path::PathBuf;
use std::process::ExitCode;

use cmop::*;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
Expand Down Expand Up @@ -115,18 +115,6 @@ fn sort(
}
}

fn get_order_from_rules(rules: &Vec<RuleKind>) -> Vec<(String, String)> {
let mut order: Vec<(String, String)> = vec![];

for r in rules {
if let RuleKind::Order(o) = r {
order.push((o.name_a.to_owned(), o.name_b.to_owned()));
}
}

order
}

/// Verifies integrity of the specified rules
fn verify(rules_path: &PathBuf) -> ExitCode {
//println!("Verifying rules from {} ...", rules_path.display());
Expand Down
16 changes: 9 additions & 7 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,31 @@ impl Rule for Order {
}

/// The Note Rule <Note for A>
/// Notes simply check the expression and notify the user if eval is true
/// The [Note] rule prints the given message when any of the following expressions is true.
#[derive(Default, Clone)]
pub struct Note {
pub comment: String,
pub expression: Option<EExpression>,
pub expressions: Vec<EExpression>,
}

impl Note {
pub fn new(comment: String, expression: EExpression) -> Self {
pub fn new(comment: String, expressions: &[EExpression]) -> Self {
Self {
comment,
expression: Some(expression),
expressions: expressions.to_vec(),
}
}
}
impl Rule for Note {
fn get_comment(&self) -> &str {
&self.comment
}
/// Notes evaluate as true if the expression evaluates as true
/// Notes evaluate as true if any of the containing expressions evaluates as true
fn eval(&self, items: &[String]) -> bool {
if let Some(expr) = &self.expression {
return expr.eval(items);
for expr in &self.expressions {
if expr.eval(items) {
return true;
}
}
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@ e
; comment
[Order]
e
c

[Note]
message
a
c
3 changes: 3 additions & 0 deletions tests/cmop/rules_warnings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Note]
message
a
9 changes: 3 additions & 6 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#[cfg(test)]
mod unit_tests {
use cmop::{
gather_mods, get_mods_from_rules, get_order_from_rules, parse_rules, read_file_as_list,
topo_sort,
};
use cmop::*;

#[test]
fn test_read_mods() {
Expand All @@ -13,13 +10,13 @@ mod unit_tests {

#[test]
fn test_parse_rules() {
let rules_path = "./tests/cmop";
let rules_path = "./tests/cmop/rules_order.txt";
assert!(parse_rules(rules_path).is_ok(), "rules parsing failed")
}

#[test]
fn test_verify_rules() {
let rules_path = "./tests/cmop";
let rules_path = "./tests/cmop/rules_order.txt";
let rules = parse_rules(rules_path).expect("rule parse failed");
let order = get_order_from_rules(&rules);
let mods = get_mods_from_rules(&order);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_rules_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod unit_rules_tests {

let rules: Vec<_> = [("a", "some a"), ("c", "some b"), ("x", "some x!")]
.iter()
.map(|e| Note::new(e.1.into(), Atomic { item: e.0.into() }.into()))
.map(|e| Note::new(e.1.into(), &[Atomic::from(e.0).into()]))
.collect();

let mut warnings: Vec<String> = vec![];
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ mod unit_tests {

let rules: Vec<_> = [("a", "some a"), ("c", "some b"), ("x", "some x!")]
.iter()
.map(|e| Note::new(e.1.into(), Atomic::from(e.0).into()))
.map(|e| Note::new(e.1.into(), &[Atomic::from(e.0).into()]))
.collect();

let mut warnings: Vec<String> = vec![];
Expand Down

0 comments on commit ae6bda2

Please sign in to comment.