use std::str::FromStr;
use crate::ParseError;
#[derive(Debug)]
pub enum FilterOperator<T> {
Eq(T),
Ne(T),
Gt(T),
Ge(T),
Lt(T),
Le(T),
EqAny(Vec<T>),
}
fn parse_single_operand<T: FromStr>(input: &str) -> Result<T, ParseError>
where
<T as FromStr>::Err: Into<ParseError>,
{
input.parse().map_err(|e: <T as FromStr>::Err| e.into())
}
fn parse_vec_operand<T: FromStr>(input: &str) -> Result<Vec<T>, ParseError>
where
<T as FromStr>::Err: Into<ParseError>,
{
input
.split(',')
.map(|segment| segment.parse())
.collect::<Result<Vec<T>, <T as FromStr>::Err>>()
.map_err(|e: <T as FromStr>::Err| e.into())
}
impl<T: FromStr> FilterOperator<Option<T>>
where
<T as FromStr>::Err: Into<ParseError>,
{
pub fn from_none(op: &str) -> Result<Self, ParseError> {
match op {
"eq" => Ok(FilterOperator::Eq(None)),
"ne" => Ok(FilterOperator::Ne(None)),
"gt" => Ok(FilterOperator::Gt(None)),
"ge" => Ok(FilterOperator::Ge(None)),
"lt" => Ok(FilterOperator::Lt(None)),
"le" => Ok(FilterOperator::Le(None)),
"in" => Ok(FilterOperator::EqAny(vec![])),
_ => Err(ParseError::UnknownOperator(op.to_owned())),
}
}
pub fn try_parse_option(op: &str, value: &str) -> Result<Self, ParseError> {
let value: FilterOperator<T> = FilterOperator::try_parse(op, value)?;
Ok(match value {
FilterOperator::Eq(v) => FilterOperator::Eq(Some(v)),
FilterOperator::Ne(v) => FilterOperator::Ne(Some(v)),
FilterOperator::Gt(v) => FilterOperator::Ne(Some(v)),
FilterOperator::Ge(v) => FilterOperator::Ne(Some(v)),
FilterOperator::Lt(v) => FilterOperator::Ne(Some(v)),
FilterOperator::Le(v) => FilterOperator::Ne(Some(v)),
FilterOperator::EqAny(v) => FilterOperator::EqAny(v.into_iter().map(Some).collect()),
})
}
}
impl<T: FromStr> FilterOperator<T>
where
<T as FromStr>::Err: Into<ParseError>,
{
pub fn try_parse(op: &str, value: &str) -> Result<Self, ParseError> {
match op {
"eq" => Ok(FilterOperator::Eq(parse_single_operand(value)?)),
"ne" => Ok(FilterOperator::Ne(parse_single_operand(value)?)),
"gt" => Ok(FilterOperator::Gt(parse_single_operand(value)?)),
"ge" => Ok(FilterOperator::Ge(parse_single_operand(value)?)),
"lt" => Ok(FilterOperator::Lt(parse_single_operand(value)?)),
"le" => Ok(FilterOperator::Le(parse_single_operand(value)?)),
"in" => Ok(FilterOperator::EqAny(parse_vec_operand(value)?)),
_ => Err(ParseError::UnknownOperator(op.to_owned())),
}
}
}