[Card] Search cards by Scryfall Tagger tag

This commit is contained in:
Lukas Brübach 2026-09-21 13:20:52 +02:00
parent 1803fce56c
commit d65d23ffce
3 changed files with 63 additions and 1 deletions

View file

@ -6,6 +6,7 @@
#include <QString>
#include <functional>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/game_specific_terms.h>
#include <libcockatrice/utility/peglib.h>
static peg::parser search(R"(
@ -17,7 +18,7 @@ ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / Somew
SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart
QueryPart <- NotQuery / SetQuery / RarityQuery / CMCQuery / FormatQuery / PowerQuery / ToughnessQuery / ColorQuery / TypeQuery / OracleQuery / FieldQuery / GenericQuery
QueryPart <- NotQuery / SetQuery / RarityQuery / CMCQuery / FormatQuery / PowerQuery / ToughnessQuery / ColorQuery / TagQuery / TypeQuery / OracleQuery / FieldQuery / GenericQuery
NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart
SetQuery <- ('e'/'set') SetExpression / ([:] FlexStringValue)
@ -38,6 +39,8 @@ Legality <- [Ll] 'egal'? / [Bb] 'anned'? / [Rr] 'estricted'
TypeQuery <- [tT] 'ype'? [:] StringValue
TagQuery <- [tT]('ags'/'ag') [:] String
Color <- < [Ww] 'hite'? / [Uu] / [Bb] 'lack'? / [Rr] 'ed'? / [Gg] 'reen'? / [Bb] 'lue'? >
ColorEx <- Color / [mc]
@ -133,6 +136,19 @@ static void setupParserRules()
const auto matcher = std::any_cast<StringMatcher>(sv[0]);
return [=](const CardData &x) -> bool { return matcher(x->getCardType()); };
};
search["TagQuery"] = [](const peg::SemanticValues &sv) -> Filter {
// Tags are stored space-separated, so matching whole tokens keeps
// `tags:ram` from matching `ramp`. Combine tags with AND:
// `tags:draw tags:ramp`.
const auto tag = std::any_cast<QString>(sv[0]).trimmed();
return [=](const CardData &x) -> bool {
const QString stored = x->getProperty(Mtg::Tags);
if (stored.isEmpty() || tag.isEmpty()) {
return false;
}
return stored.split(" ", Qt::SkipEmptyParts).contains(tag, Qt::CaseInsensitive);
};
};
search["SetQuery"] = [](const peg::SemanticValues &sv) -> Filter {
if (sv.choice() == 1) {
auto matcher = std::any_cast<StringMatcher>(sv[0]);