always return false for fields that aren’t set

This means a search for level<4 won’t return link monsters.
Previously, a monster without level was considered to be level 0.
This commit is contained in:
kageru 2023-06-26 14:27:53 +02:00
parent 0754f40706
commit b1eac3fa00
3 changed files with 60 additions and 8 deletions

View File

@ -193,6 +193,43 @@ pub mod tests {
]
}"#;
pub const RAW_LINK_MONSTER: &str = r#"
{
"id": 49202162,
"name": "Black Luster Soldier - Soldier of Chaos",
"type": "Link Monster",
"frameType": "link",
"desc": "3 monsters with different names\r\nIf this card was Link Summoned using a Level 7 or higher monster(s) as material, your opponent cannot target it with card effects, also it cannot be destroyed by your opponent's card effects. When this card destroys an opponent's monster by battle: You can activate 1 of these effects;\r\n● This card gains 1500 ATK.\r\n● This card can make a second attack during the Battle Phase of your next turn.\r\n● Banish 1 card on the field.",
"atk": 3000,
"race": "Warrior",
"attribute": "EARTH",
"archetype": "Black Luster Soldier",
"linkval": 3,
"linkmarkers": [
"Top",
"Bottom-Left",
"Bottom-Right"
],
"card_sets": [
{
"set_name": "OTS Tournament Pack 17",
"set_code": "OP17-EN003",
"set_rarity": "Ultimate Rare",
"set_rarity_code": "(UtR)",
"set_price": "75.77"
}
],
"card_images": [
{
"id": 49202162,
"image_url": "https://images.ygoprodeck.com/images/cards/49202162.jpg",
"image_url_small": "https://images.ygoprodeck.com/images/cards_small/49202162.jpg",
"image_url_cropped": "https://images.ygoprodeck.com/images/cards_cropped/49202162.jpg"
}
]
}
"#;
#[test]
fn test_spell() {
let coffin: Card = serde_json::from_str(RAW_SPELL).unwrap();

View File

@ -56,12 +56,12 @@ pub type CardFilter = Box<dyn Fn(&SearchCard) -> bool>;
fn get_field_value(card: &SearchCard, field: Field) -> Value {
match field {
Field::Atk => Value::Numerical(card.atk.unwrap_or(0)),
Field::Def => Value::Numerical(card.def.unwrap_or(0)),
Field::Atk => card.atk.map(Value::Numerical).unwrap_or_default(),
Field::Def => card.def.map(Value::Numerical).unwrap_or_default(),
Field::Legal => Value::Numerical(card.legal_copies),
Field::Level => Value::Numerical(card.level.unwrap_or(0)),
Field::LinkRating => Value::Numerical(card.link_rating.unwrap_or(0)),
Field::Year => Value::Numerical(card.original_year.unwrap_or(0)),
Field::Level => card.level.map(Value::Numerical).unwrap_or_default(),
Field::LinkRating => card.link_rating.map(Value::Numerical).unwrap_or_default(),
Field::Year => card.original_year.map(Value::Numerical).unwrap_or_default(),
Field::Set => Value::Multiple(card.sets.clone().into_iter().map(Value::String).collect()),
Field::Type => Value::String(card.r#type.clone()),
Field::Attribute => Value::String(card.attribute.clone().unwrap_or_default()),
@ -73,10 +73,12 @@ fn get_field_value(card: &SearchCard, field: Field) -> Value {
fn filter_value(op: &Operator, field_value: &Value, query_value: &Value) -> bool {
match (field_value, query_value) {
(Value::None, _) => false,
(Value::Numerical(field), Value::Numerical(query)) => op.filter_number(Some(*field), *query),
(Value::String(field), Value::String(query)) => match op {
Operator::Equal => field.contains(query),
Operator::NotEqual => !field.contains(query),
// greater/less than aren’t supported for string fields.
_ => false,
},
// Currently only for sets the card was released in.
@ -105,7 +107,10 @@ pub fn build_filter(RawCardFilter(field, op, value): RawCardFilter) -> Result<Ca
#[cfg(test)]
mod tests {
use super::*;
use crate::{data::tests::RAW_MONSTER, parser::parse_filters};
use crate::{
data::tests::{RAW_LINK_MONSTER, RAW_MONSTER},
parser::parse_filters,
};
#[test]
fn level_filter_test() {
@ -123,6 +128,13 @@ mod tests {
assert!(!filter_level_5[0](&lacooda));
}
#[test]
fn filter_by_level_should_exclude_link_monsters() {
let bls = SearchCard::from(&serde_json::from_str::<Card>(RAW_LINK_MONSTER).unwrap());
let filter = parse_filters("l<=4").unwrap().1;
assert!(!filter[0](&bls));
}
#[test]
fn set_filter_test() {
let lacooda = SearchCard::from(&serde_json::from_str::<Card>(RAW_MONSTER).unwrap());

View File

@ -232,11 +232,13 @@ impl Display for RawCardFilter {
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub enum Value {
String(String),
Numerical(i32),
Multiple(Vec<Value>),
#[default]
None,
}
impl Display for Value {
@ -252,7 +254,8 @@ impl Display for Value {
Self::Numerical(n) => write!(f, "{n}"),
Self::Multiple(m) => {
write!(f, "one of [{}]", m.iter().map(Value::to_string).join(", "))
}
},
Self::None => f.write_str("none"),
}
}
}