clean up multiple filter parsing
This commit is contained in:
parent
55bb41958b
commit
bd6e92fa2d
@ -66,7 +66,7 @@ fn get_field_value(card: &SearchCard, field: Field) -> Value {
|
||||
// On the bright side, this means `set:HA` matches all Hidden Arsenals (plus reprints in HAC), but also all other set codes that contain HA.
|
||||
Field::Set => Value::String(card.sets.join(" ")),
|
||||
Field::Type => Value::String(card.r#type.clone()),
|
||||
Field::Attribute => Value::String(card.attribute.clone().unwrap_or_else(|| "".to_string())),
|
||||
Field::Attribute => Value::String(card.attribute.clone().unwrap_or_default()),
|
||||
Field::Class => Value::String(card.card_type.clone()),
|
||||
Field::Name => Value::String(card.name.clone()),
|
||||
Field::Text => Value::String(card.text.clone()),
|
||||
@ -106,8 +106,15 @@ mod tests {
|
||||
#[test]
|
||||
fn level_filter_test() {
|
||||
let lacooda = SearchCard::from(&serde_json::from_str::<Card>(RAW_MONSTER).unwrap());
|
||||
let lacooda_but_level_4 = SearchCard { level: Some(4), ..lacooda.clone() };
|
||||
|
||||
let filter_level_3 = parse_filters("l=3").unwrap();
|
||||
assert!(filter_level_3.1[0](&lacooda));
|
||||
|
||||
let filter_level_3_4 = parse_filters("l=3|4").unwrap();
|
||||
assert!(filter_level_3_4.1[0](&lacooda));
|
||||
assert!(filter_level_3_4.1[0](&lacooda_but_level_4));
|
||||
|
||||
let filter_level_5 = parse_filters("l=5").unwrap();
|
||||
assert!(!filter_level_5.1[0](&lacooda));
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ fn word_non_empty(input: &str) -> IResult<&str, &str> {
|
||||
}
|
||||
|
||||
fn sanitize(query: &str) -> Result<String, String> {
|
||||
if query.contains(OPERATOR_CHARS) {
|
||||
if query.contains(OPERATOR_CHARS) || query.is_empty() {
|
||||
Err(format!("Invalid query: {query}"))
|
||||
} else {
|
||||
Ok(query.to_lowercase())
|
||||
@ -91,30 +91,25 @@ fn values(input: &str) -> IResult<&str, Value> {
|
||||
take_until1(" "),
|
||||
rest,
|
||||
)),
|
||||
|i: &str| {
|
||||
if i.contains('|') {
|
||||
let items: Vec<_> = i.split('|').collect();
|
||||
let mut values = Vec::new();
|
||||
|
||||
for item in items {
|
||||
match item.parse::<i32>() {
|
||||
Ok(n) => values.push(Value::Numerical(n)),
|
||||
Err(_) => values.push(Value::String(sanitize(item)?)),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Multiple(values))
|
||||
} else {
|
||||
match i.parse() {
|
||||
Ok(n) => Ok(Value::Numerical(n)),
|
||||
Err(_) if i.is_empty() => Err("empty filter argument".to_string()),
|
||||
Err(_) => Ok(Value::String(sanitize(i)?)),
|
||||
}
|
||||
}
|
||||
},
|
||||
parse_values,
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_values(input: &str) -> Result<Value, String> {
|
||||
let values = input.split('|').map(parse_single_value).collect::<Result<Vec<Value>, String>>()?;
|
||||
Ok(match values.as_slice() {
|
||||
[v] => v.clone(),
|
||||
_ => Value::Multiple(values),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_single_value(input: &str) -> Result<Value, String> {
|
||||
Ok(match input.parse() {
|
||||
Ok(n) => Value::Numerical(n),
|
||||
Err(_) => Value::String(sanitize(input)?),
|
||||
})
|
||||
}
|
||||
|
||||
/// Ordinals are given highest = fastest to filter.
|
||||
/// This is used to sort filters before applying them.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
@ -283,6 +278,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test_case("atk<=>1")]
|
||||
#[test_case("atk=50|")]
|
||||
#[test_case("def=|")]
|
||||
#[test_case("l===10")]
|
||||
#[test_case("t=")]
|
||||
#[test_case("=100")]
|
||||
@ -324,7 +321,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_filters_with_multiple_values() {
|
||||
fn parse_multiple_values() {
|
||||
let input = "level=4|5|6";
|
||||
let expected_output = vec![RawCardFilter(
|
||||
Field::Level,
|
||||
|
Loading…
Reference in New Issue
Block a user