use std::collections::VecDeque;
use crate::{
collection::processes::ProcessHarvest,
widgets::query::{
And, COMPARISON_LIST, Prefix, QueryOptions, QueryProcessor, QueryResult, error::QueryError,
},
};
#[derive(Debug)]
pub(super) struct Or {
pub(super) lhs: And,
pub(super) rhs: Option<Box<And>>,
}
impl Or {
pub(super) fn check(&self, process: &ProcessHarvest, is_using_command: bool) -> bool {
if let Some(rhs) = &self.rhs {
self.lhs.check(process, is_using_command) || rhs.check(process, is_using_command)
} else {
self.lhs.check(process, is_using_command)
}
}
}
impl QueryProcessor for Or {
fn process(query: &mut VecDeque<String>, options: &QueryOptions) -> QueryResult<Self>
where
Self: Sized,
{
const OR_LIST: [&str; 2] = ["or", "||"];
let mut lhs = And::process(query, options)?;
let mut rhs: Option<Box<And>> = None;
while let Some(queue_top) = query.front() {
let current_lowercase = queue_top.to_lowercase();
if OR_LIST.contains(¤t_lowercase.as_str()) {
query.pop_front();
rhs = Some(Box::new(And::process(query, options)?));
if let Some(queue_next) = query.front() {
if OR_LIST.contains(&queue_next.to_lowercase().as_str()) {
lhs = And {
lhs: Prefix::Or(Box::new(Or { lhs, rhs })),
rhs: None,
};
rhs = None;
}
} else {
break;
}
} else if COMPARISON_LIST.contains(¤t_lowercase.as_str()) {
return Err(QueryError::new("Comparison not valid here"));
} else {
break;
}
}
Ok(Or { lhs, rhs })
}
}