Merge branch 'filter' into 'main'

Add filter function

See merge request vato007/coster-rs!5
This commit is contained in:
Michael Pivato
2023-07-28 10:20:28 +00:00
2 changed files with 77 additions and 0 deletions

75
src/filter.rs Normal file
View File

@@ -0,0 +1,75 @@
use std::{
collections::HashMap,
io::{Read, Write},
str::FromStr,
};
pub enum Comparator<T: PartialOrd> {
EQUAL(T),
NOT_EQUAL(T),
GREATER_THAN(T),
LESS_THAN(T),
IN(Vec<T>),
NOT_IN(Vec<T>),
}
impl<T: PartialOrd> Comparator<T> {
pub fn is_valid(&self, value: T) -> bool {
match self {
Comparator::EQUAL(v) => value == *v,
Comparator::NOT_EQUAL(v) => value != *v,
Comparator::GREATER_THAN(v) => value > *v,
Comparator::LESS_THAN(v) => value < *v,
Comparator::IN(v) => v.contains(&value),
Comparator::NOT_IN(v) => !v.contains(&value),
}
}
}
pub trait FieldName {
// Name of the field this validator should work on
fn get_field_name(&self) -> String;
}
pub trait DataValidator: FieldName {
// Whether the given value is valid for the validator
fn is_valid(&self, s: &String) -> bool;
}
pub struct FilterRule<T: PartialOrd> {
column_name: String,
comparator: Comparator<T>,
}
impl<T: PartialOrd> FieldName for FilterRule<T> {
fn get_field_name(&self) -> String {
self.column_name.clone()
}
}
impl<T: FromStr + PartialOrd> DataValidator for FilterRule<T> {
fn is_valid(&self, s: &String) -> bool {
s.parse().map_or(false, |f| self.comparator.is_valid(f))
}
}
/**
* Write all lines from the input file to the output file, skipping records
* that don't satisfy the filter criteria
*/
pub fn filter_file(
rules: Vec<&dyn DataValidator>,
input: &mut csv::Reader<impl Read>,
output: &mut csv::Writer<impl Write>,
) -> anyhow::Result<()> {
for line in input.deserialize() {
let line: HashMap<String, String> = line?;
if rules.iter().all(|rule| {
line.get(&rule.get_field_name())
.map_or(true, |value| rule.is_valid(value))
}) {
output.serialize(line)?;
}
}
Ok(())
}

View File

@@ -15,6 +15,8 @@ pub use self::shared_models::*;
pub mod link;
pub mod filter;
#[no_mangle]
pub extern "C" fn move_money_from_text(
rules: *const c_char,