use crate::message::stomp_message::StompMessage;
#[derive(Debug, PartialEq)]
enum Operator {
Equal,
NotEqual,
NumericEquals,
GreaterThan,
LessThan,
}
#[derive(Debug)]
pub struct Filter {
hdr: String,
op: Operator,
value: String,
}
impl Filter {
pub fn parse(definition: &String) -> Result<Filter, ()> {
let mut state= 0;
let mut hdr = String::new();
let mut operator = String::new();
let mut value= String::new();
for c in definition.chars() {
match state {
0 => {
if (c >= 'a' && c <= 'z') || c == '-' {
hdr.push(c);
} else {
operator.push(c);
state += 1;
}
},
1 => {
if c == '=' || c == '!' || c == '>' || c == '<' {
operator.push(c);
} else {
value.push(c);
state += 1;
}
}
_ => {
value.push(c);
}
}
}
let op;
match operator.as_str() {
"=" => op = Operator::Equal,
"==" => op = Operator::NumericEquals,
"!=" => op = Operator::NotEqual,
">" => op = Operator::GreaterThan,
"<" => op = Operator::LessThan,
_ => op = Operator::Equal,
}
if op == Operator::GreaterThan || op == Operator::GreaterThan {
if let Err(_) = value.parse::<i64>() {
return Err(());
}
}
Ok(Filter { hdr, op, value })
}
pub fn matches_message(&self, message: &StompMessage) -> bool {
if let Some(to_match) = message.get_header(&self.hdr) {
match self.op {
Operator::Equal => return to_match == self.value.as_str(),
Operator::NotEqual => return to_match != self.value.as_str(),
Operator::NumericEquals => {
if let Ok(int) = to_match.parse::<i64>(){
return int == self.value.parse::<i64>().unwrap();
}
return false;
},
Operator::LessThan => {
if let Ok(int) = to_match.parse::<i64>(){
return int < self.value.parse::<i64>().unwrap();
}
return false;
},
Operator::GreaterThan => {
if let Ok(int) = to_match.parse::<i64>(){
return int > self.value.parse::<i64>().unwrap();
}
return false;
},
};
}
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::message::stomp_message::Ownership;
#[test]
pub fn test_string_equal() {
let filter = Filter::parse(&String::from("grp=1")).unwrap();
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "1");
if ! filter.matches_message(&message) {
panic!("grp=1");
}
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "2");
if filter.matches_message(&message) {
panic!("grp=2");
}
}
#[test]
pub fn test_numeric_equal() {
let filter = Filter::parse(&String::from("grp==1")).unwrap();
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "1");
if ! filter.matches_message(&message) {
panic!("grp==1");
}
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "2");
if filter.matches_message(&message) {
panic!("grp==2");
}
}
#[test]
pub fn test_numeric_gt() {
let filter = Filter::parse(&String::from("grp>1")).unwrap();
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "2");
if ! filter.matches_message(&message) {
panic!("grp>2");
}
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "1");
if filter.matches_message(&message) {
panic!("grp>1");
}
}
#[test]
pub fn test_numeric_lt() {
let filter = Filter::parse(&String::from("grp<1")).unwrap();
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "0");
if ! filter.matches_message(&message) {
panic!("grp<0");
}
let mut message = StompMessage::new(Ownership::Destination);
message.add_header("grp", "1");
if filter.matches_message(&message) {
panic!("grp<1");
}
}
}