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.
|
// 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::Set => Value::String(card.sets.join(" ")),
|
||||||
Field::Type => Value::String(card.r#type.clone()),
|
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::Class => Value::String(card.card_type.clone()),
|
||||||
Field::Name => Value::String(card.name.clone()),
|
Field::Name => Value::String(card.name.clone()),
|
||||||
Field::Text => Value::String(card.text.clone()),
|
Field::Text => Value::String(card.text.clone()),
|
||||||
@ -106,8 +106,15 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn level_filter_test() {
|
fn level_filter_test() {
|
||||||
let lacooda = SearchCard::from(&serde_json::from_str::<Card>(RAW_MONSTER).unwrap());
|
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();
|
let filter_level_3 = parse_filters("l=3").unwrap();
|
||||||
assert!(filter_level_3.1[0](&lacooda));
|
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();
|
let filter_level_5 = parse_filters("l=5").unwrap();
|
||||||
assert!(!filter_level_5.1[0](&lacooda));
|
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> {
|
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}"))
|
Err(format!("Invalid query: {query}"))
|
||||||
} else {
|
} else {
|
||||||
Ok(query.to_lowercase())
|
Ok(query.to_lowercase())
|
||||||
@ -91,30 +91,25 @@ fn values(input: &str) -> IResult<&str, Value> {
|
|||||||
take_until1(" "),
|
take_until1(" "),
|
||||||
rest,
|
rest,
|
||||||
)),
|
)),
|
||||||
|i: &str| {
|
parse_values,
|
||||||
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)?)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)(input)
|
)(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.
|
/// Ordinals are given highest = fastest to filter.
|
||||||
/// This is used to sort filters before applying them.
|
/// This is used to sort filters before applying them.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
@ -283,6 +278,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test_case("atk<=>1")]
|
#[test_case("atk<=>1")]
|
||||||
|
#[test_case("atk=50|")]
|
||||||
|
#[test_case("def=|")]
|
||||||
#[test_case("l===10")]
|
#[test_case("l===10")]
|
||||||
#[test_case("t=")]
|
#[test_case("t=")]
|
||||||
#[test_case("=100")]
|
#[test_case("=100")]
|
||||||
@ -324,7 +321,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_raw_filters_with_multiple_values() {
|
fn parse_multiple_values() {
|
||||||
let input = "level=4|5|6";
|
let input = "level=4|5|6";
|
||||||
let expected_output = vec![RawCardFilter(
|
let expected_output = vec![RawCardFilter(
|
||||||
Field::Level,
|
Field::Level,
|
||||||
|
Loading…
Reference in New Issue
Block a user