diff --git a/src/data.rs b/src/data.rs index 9dbd9b5..9340b66 100644 --- a/src/data.rs +++ b/src/data.rs @@ -11,26 +11,43 @@ pub struct CardInfo { #[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)] pub struct Card { - pub id: usize, + pub id: usize, #[serde(rename = "type")] - pub card_type: String, - pub name: String, + pub card_type: String, + pub name: String, #[serde(rename = "desc")] - pub text: String, + pub text: String, // Will also be None for ? - pub atk: Option, - pub def: Option, - pub attribute: Option, + pub atk: Option, + pub def: Option, + pub attribute: Option, #[serde(rename = "race")] - pub r#type: String, + pub r#type: String, // also includes rank - pub level: Option, + pub level: Option, #[serde(rename = "linkval")] - pub link_rating: Option, + pub link_rating: Option, #[serde(rename = "linkmarkers")] - pub link_arrows: Option>, + pub link_arrows: Option>, #[serde(default)] - pub card_sets: Vec, + pub card_sets: Vec, + pub banlist_info: Option, +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Copy, Default)] +pub struct BanlistInfo { + #[serde(default)] + pub ban_tcg: BanlistStatus, +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Copy, Default)] +pub enum BanlistStatus { + Banned = 0, + Limited = 1, + #[serde(rename = "Semi-Limited")] + SemiLimited = 2, + #[default] + Unlimited = 3, } #[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)] diff --git a/src/filter.rs b/src/filter.rs index 41c3405..d4c9ccc 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -1,7 +1,7 @@ use time::Date; use crate::{ - data::Card, + data::{BanlistStatus, Card}, parser::{Field, Operator, RawCardFilter, Value, OPERATOR_CHARS}, SETS_BY_NAME, }; @@ -23,6 +23,7 @@ pub struct SearchCard { link_arrows: Option>, sets: Vec, original_year: Option, + legal_copies: i32, } impl From<&Card> for SearchCard { @@ -48,6 +49,7 @@ impl From<&Card> for SearchCard { }) .map(Date::year) .min(), + legal_copies: card.banlist_info.map(|bi| bi.ban_tcg).unwrap_or(BanlistStatus::Unlimited) as i32, } } } @@ -77,6 +79,7 @@ pub fn build_filter(query: RawCardFilter) -> Result { RawCardFilter(Field::Level, op, Value::Numerical(n)) => Box::new(move |card| op.filter_number(card.level, n)), RawCardFilter(Field::LinkRating, op, Value::Numerical(n)) => Box::new(move |card| op.filter_number(card.link_rating, n)), RawCardFilter(Field::Year, op, Value::Numerical(n)) => Box::new(move |card| op.filter_number(card.original_year, n)), + RawCardFilter(Field::Legal, op, Value::Numerical(n)) => Box::new(move |card| op.filter_number(Some(card.legal_copies), n)), RawCardFilter(Field::Type, Operator::Equal, Value::String(s)) => Box::new(move |card| card.r#type == s), RawCardFilter(Field::Type, Operator::NotEqual, Value::String(s)) => Box::new(move |card| card.r#type != s), RawCardFilter(Field::Attribute, Operator::Equal, Value::String(s)) => Box::new(move |card| card.attribute.contains(&s)), diff --git a/src/parser.rs b/src/parser.rs index 1505f54..7011fa4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -64,6 +64,7 @@ fn value(input: &str) -> IResult<&str, Value> { pub enum Field { Atk = 1, Def = 2, + Legal = 3, Level = 4, LinkRating = 6, Year = 8, @@ -89,6 +90,7 @@ impl Display for Field { Self::LinkRating => "link rating", Self::Set => "set", Self::Year => "year", + Self::Legal => "allowed copies", }) } } @@ -108,6 +110,7 @@ impl FromStr for Field { "name" => Self::Name, "set" | "s" => Self::Set, "year" | "y" => Self::Year, + "legal" | "copies" => Self::Legal, _ => Err(s.to_string())?, }) } diff --git a/static/help.html b/static/help.html index 174269d..b0f7944 100644 --- a/static/help.html +++ b/static/help.html @@ -13,6 +13,7 @@ Currently supported search fields are:
  • The attribute (or attr or a) of a card. This is “Light”, “Dark”, “Earth”, etc.
  • The text (or effect, eff, e, or o) of a card. This is either the effect or flavor text (for normal monsters). For pendulum cards, this searches in both pendulum and monster effects. The o alias is to help my muscle memory coming from Scryfall.
  • The set (or s) a card was printed in. This considers all printings, not just the original.
  • +
  • The copies (or legal) you’re allowed to play according to the current banlist.
  • Anything not associated with a search field is interpreted as a search in the card name, so l:4 utopia will show all level/rank 4 monsters with “Utopia” in their name.
    If your search contains spaces (e.g. searching for an effect that says “destroy that target”), the text must be quoted like effect:"destroy that target". @@ -34,4 +35,5 @@ The following search operators are supported:
  • All Synchro monsters that are Dark attribute, level 5 or higher, and have exactly 2200 ATK: c:synchro a:dark l>=5 atk:2200
  • All counter traps that can negate summons: c:trap t:counter e:"negate the summon"
  • All effect monsters printed in Legend of Blue-Eyes: set:lob c:effect
  • +
  • All Zoodiac cards that are currently banned: legal:0 zoodiac