Compare commits

..

3 Commits

Author SHA1 Message Date
2dd4f3d696 Added some more fields
Got most of them done. Added a couple of cards too
2025-02-01 01:18:38 +00:00
d8e0b2c07b Seems to be alright at deserialising the things so far 2025-01-31 23:45:43 +00:00
871d2af2da Added a first test to see whether a card is available 2025-01-31 23:31:58 +00:00
5 changed files with 687 additions and 16 deletions

View File

@@ -7,3 +7,4 @@ edition = "2021"
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.138"

View File

@@ -1,8 +1,9 @@
use serde::Deserialize; use serde::{Deserialize};
// Info from here: // Info from here:
// https://scryfall.com/docs/api/cards // https://scryfall.com/docs/api/cards
#[derive(Deserialize)] #[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ScryfallCard { struct ScryfallCard {
// Core Card Fields // Core Card Fields
pub arena_id: Option<u64>, pub arena_id: Option<u64>,
@@ -23,27 +24,93 @@ struct ScryfallCard {
pub uri: String, //URI pub uri: String, //URI
// Gameplay Fields // Gameplay Fields
// https://scryfall.com/docs/api/cards#gameplay-fields
pub all_parts: Option<Vec<ScryfallRelatedCardObject>>, pub all_parts: Option<Vec<ScryfallRelatedCardObject>>,
pub card_faces: Option<Vec<ScryfallCardFaceObject>>,
// NOTE: Much of the next is a repeat of what's in the ScryfallCardFaceObject if you change something here, change something there
// NOTE: Probably a bad idea to rename color -> colour just for the sake
pub cmc: Option<f64>, // TODO: Make this a proper Decimal - see "Little Girl" card for example of cmc of 0.5
#[serde(rename = "color_identity")]
pub colour_identity: Vec<Colour>,
#[serde(rename = "color_indicator")]
pub colour_indicator: Option<Vec<Colour>>,
#[serde(rename = "colors")]
pub colours: Option<Vec<Colour>>,
pub edhrec_rank: Option<u64>,
pub defence: Option<String>,
pub hand_modifier: Option<String>,
pub keywords: Vec<String>, // Words like "Flying"
pub legalities: FormatLegalities,
pub life_modifier: Option<String>,
pub loyalty: Option<String>,
pub mana_cost: Option<String>,
pub name: String,
pub oracle_text: Option<String>,
pub penny_rank: Option<u64>,
pub power: Option<String>,
pub produced_mana: Option<Vec<Colour>>,
pub reserved: bool,
pub toughness: Option<String>,
pub type_line: String,
// Print Fields
// https://scryfall.com/docs/api/cards#print-fields
pub artist: Option<String>,
pub artist_ids: Option<Vec<String>>,
pub attraction_lights: Option<Vec<String>>, // TODO: I'm not actually sure what these look like - I should test
pub booster: bool,
#[serde(rename = "border_color")]
pub border_colour: BorderColour,
pub card_back_id: String, // UUID
pub collector_number: String,
pub content_warning: Option<bool>,
pub digital: bool,
pub finishes: Vec<Finish>,
#[serde(rename = "flavor_name")]
pub flavour_name: Option<String>,
#[serde(rename = "flavor_text")]
pub flavour_text: Option<String>,
pub frame_effects: Option<Vec<FrameEffect>>,
pub frame: Frame,
pub full_art: bool,
pub games: Vec<Game>,
pub highres_image: bool,
pub illustration_id: Option<String>, // UUID
pub image_status: ImageStatus,
pub image_uris: ImageURIs,
pub oversized: bool,
pub prices: Prices,
pub printed_name: Option<String>,
pub printed_text: Option<String>,
pub printed_type_line: Option<String>,
pub promo: bool,
pub promo_types: Vec<String>, // TODO: Check what types exist - could be a enumeratable selection
pub purchase_uris: Option<Vec<bool>>, // FIXME
pub rarity: Rarity,
// TODO - the rest (and the purachase URIs above)
} }
// https://scryfall.com/docs/api/cards#card-face-objects // https://scryfall.com/docs/api/cards#card-face-objects
#[derive(Deserialize)] #[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ScryfallCardFaceObject { struct ScryfallCardFaceObject {
pub artist: Option<String>, pub artist: Option<String>,
pub artist_id: Option<String>, // UUID pub artist_id: Option<String>, // UUID
pub cmc: Option<f64>, // TODO: Make this a proper Decimal - see "Little Girl" card for example of cmc of 0.5 pub cmc: Option<f64>, // TODO: Make this a proper Decimal - see "Little Girl" card for example of cmc of 0.5
#[serde(rename = "color_identity")]
pub colour_identity: Vec<Colour>, pub colour_identity: Vec<Colour>,
#[serde(rename = "color_indicator")]
pub colour_indicator: Option<Vec<Colour>>, pub colour_indicator: Option<Vec<Colour>>,
#[serde(rename = "colors")]
pub colours: Option<Vec<Colour>>, pub colours: Option<Vec<Colour>>,
pub defence: Option<String>, pub defence: Option<String>,
pub edhrec_rank: Option<u64>, // TODO: Complete
} }
// https://scryfall.com/docs/api/cards#related-card-objects // https://scryfall.com/docs/api/cards#related-card-objects
#[derive(Deserialize)] #[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ScryfallRelatedCardObject { struct ScryfallRelatedCardObject {
pub id: String, // UUID pub id: String, // UUID
pub object: String, // Always "related_card" pub object: String, // Always "related_card"
@@ -53,32 +120,254 @@ struct ScryfallRelatedCardObject {
pub uri: String // URI pub uri: String // URI
} }
#[derive(Deserialize, PartialEq)] #[derive(Deserialize, PartialEq, Debug)]
enum Colour { enum Colour {
#[serde(rename = "W")]
White, White,
#[serde(rename = "U")]
Blue, Blue,
#[serde(rename = "B")]
Black, Black,
#[serde(rename = "R")]
Red, Red,
#[serde(rename = "G")]
Green, Green,
Colourless
} }
pub fn deserialise_card(data: String) -> Card { #[derive(Deserialize, Debug)]
enum Legality {
Card #[serde(rename = "legal")]
Legal,
#[serde(rename = "not_legal")]
NotLegal,
#[serde(rename = "banned")]
Banned,
#[serde(rename = "restricted")]
Restricted,
} }
pub fn add(left: usize, right: usize) -> usize { #[allow(dead_code)]
left + right #[derive(Deserialize, Debug)]
struct FormatLegalities {
standard: Legality,
future: Legality,
historic: Legality,
timeless: Legality,
gladiator: Legality,
pioneer: Legality,
explorer: Legality,
modern: Legality,
legacy: Legality,
pauper: Legality,
vintage: Legality,
penny: Legality,
commander: Legality,
oathbreaker: Legality,
standardbrawl: Legality,
brawl: Legality,
alchemy: Legality,
paupercommander: Legality,
duel: Legality,
oldschool: Legality,
premodern: Legality,
predh: Legality
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum BorderColour {
#[serde(rename = "black")]
Black,
#[serde(rename = "white")]
White,
#[serde(rename = "borderless")]
Borderless,
#[serde(rename = "yellow")]
Yellow,
#[serde(rename = "silver")]
Silver,
#[serde(rename = "gold")]
Gold
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum Finish {
#[serde(rename = "foil")]
Foil,
#[serde(rename = "nonfoil")]
NonFoil,
#[serde(rename = "etched")]
Etched
}
// https://scryfall.com/docs/api/frames#frames
// This is probably dumb...
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum Frame {
#[serde(rename = "1993")]
NinetyThree,
#[serde(rename = "1997")]
NinetySeven,
#[serde(rename = "2003")]
OhThree,
#[serde(rename = "2015")]
OhFifteen,
#[serde(rename = "future")]
Future
}
// https://scryfall.com/docs/api/frames#frame-effects
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum FrameEffect {
#[serde(rename = "legendary")]
Legendary,
#[serde(rename = "miracle")]
Miracle,
#[serde(rename = "enchantment")]
Enchantment,
#[serde(rename = "draft")]
Draft,
#[serde(rename = "devoid")]
Devoid,
#[serde(rename = "tombstone")]
Tombstone,
#[serde(rename = "colorshifted")]
Colourshifted,
#[serde(rename = "inverted")]
Inverted,
#[serde(rename = "sunmoondfc")]
SunMoonDFC,
#[serde(rename = "compasslanddfc")]
CompassLandDFC,
#[serde(rename = "originpwdfc")]
OriginPwDFC,
#[serde(rename = "mooneldrazidfc")]
MoonEldraziDFC,
#[serde(rename = "waxingandwaningmoondfc")]
WaxingAndWaningMoonDFC,
#[serde(rename = "showcase")]
Showcase,
#[serde(rename = "extendedart")]
ExtendedArt,
#[serde(rename = "companion")]
Companion,
#[serde(rename = "etched")]
Etched,
#[serde(rename = "snow")]
Snow,
#[serde(rename = "lesson")]
Lesson,
#[serde(rename = "shatteredglass")]
ShatteredGlass,
#[serde(rename = "convertdfc")]
ConvertDFC,
#[serde(rename = "fandfc")]
FanDFC,
#[serde(rename = "upsidedowndfc")]
UpsideDownDFC,
#[serde(rename = "spree")]
Spree
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum Game {
#[serde(rename = "paper")]
Paper,
#[serde(rename = "mtgo")]
MTGO,
#[serde(rename = "arena")]
Arena
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum ImageStatus {
#[serde(rename = "missing")]
Missing,
#[serde(rename = "placeholder")]
Placeholder,
#[serde(rename = "lowres")]
LowResolution,
#[serde(rename = "highres_scan")]
HighResolutionScan
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ImageURIs {
png: Option<String>,
border_crop: Option<String>,
art_crop: Option<String>,
large: Option<String>,
normal: Option<String>,
small: Option<String>
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct Prices {
usd: Option<String>, // TODO Convert to f64?
usd_foil: Option<String>,
usd_etched: Option<String>,
eur: Option<String>,
eur_foil: Option<String>,
tix: Option<String>
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
enum Rarity {
#[serde(rename = "common")]
Common,
#[serde(rename = "uncommon")]
Uncommon,
#[serde(rename = "rare")]
Rare,
#[serde(rename = "special")]
Special,
#[serde(rename = "mythic")]
Mythic,
#[serde(rename = "bonus")]
Bonus
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use std::path::PathBuf;
use std::fs;
#[test] #[test]
fn it_works() { fn deserialise_nissa() {
let result = add(2, 2); let mut f = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
assert_eq!(result, 4); f.push("test_files/nissa.json");
assert!(f.exists());
let fc = fs::read_to_string(f).unwrap();
let nissa: ScryfallCard = serde_json::from_str(&fc).unwrap();
println!("{:#?}", nissa);
}
#[test]
fn deserialise_black_lotus() {
let mut f = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
f.push("test_files/black_lotus.json");
assert!(f.exists());
let fc = fs::read_to_string(f).unwrap();
let bl: ScryfallCard = serde_json::from_str(&fc).unwrap();
println!("{:#?}", bl);
}
#[test]
fn deserialise_little_girl() {
let mut f = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
f.push("test_files/little_girl.json");
assert!(f.exists());
let fc = fs::read_to_string(f).unwrap();
let lg: ScryfallCard = serde_json::from_str(&fc).unwrap();
println!("{:#?}", lg);
} }
} }

View File

@@ -0,0 +1,117 @@
{
"object": "card",
"id": "f5d24a5b-c950-4fd9-99e6-a4b979d915b3",
"oracle_id": "5089ec1a-f881-4d55-af14-5d996171203b",
"multiverse_ids": [],
"name": "Black Lotus",
"lang": "en",
"released_at": "2023-12-08",
"uri": "https://api.scryfall.com/cards/f5d24a5b-c950-4fd9-99e6-a4b979d915b3",
"scryfall_uri": "https://scryfall.com/card/ovnt/2023NA/black-lotus?utm_source=api",
"layout": "normal",
"highres_image": false,
"image_status": "lowres",
"image_uris": {
"small": "https://cards.scryfall.io/small/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.jpg?1738105453",
"normal": "https://cards.scryfall.io/normal/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.jpg?1738105453",
"large": "https://cards.scryfall.io/large/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.jpg?1738105453",
"png": "https://cards.scryfall.io/png/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.png?1738105453",
"art_crop": "https://cards.scryfall.io/art_crop/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.jpg?1738105453",
"border_crop": "https://cards.scryfall.io/border_crop/front/f/5/f5d24a5b-c950-4fd9-99e6-a4b979d915b3.jpg?1738105453"
},
"mana_cost": "{0}",
"cmc": 0,
"type_line": "Artifact",
"oracle_text": "{T}, Sacrifice Black Lotus: Add three mana of any one color.",
"colors": [],
"color_identity": [],
"keywords": [],
"produced_mana": [
"B",
"G",
"R",
"U",
"W"
],
"legalities": {
"standard": "not_legal",
"future": "not_legal",
"historic": "not_legal",
"timeless": "not_legal",
"gladiator": "not_legal",
"pioneer": "not_legal",
"explorer": "not_legal",
"modern": "not_legal",
"legacy": "banned",
"pauper": "not_legal",
"vintage": "restricted",
"penny": "not_legal",
"commander": "banned",
"oathbreaker": "banned",
"standardbrawl": "not_legal",
"brawl": "not_legal",
"alchemy": "not_legal",
"paupercommander": "not_legal",
"duel": "banned",
"oldschool": "not_legal",
"premodern": "not_legal",
"predh": "banned"
},
"games": [
"paper"
],
"reserved": true,
"foil": false,
"nonfoil": true,
"finishes": [
"nonfoil"
],
"oversized": true,
"promo": false,
"reprint": true,
"variation": false,
"set_id": "c6a6b61b-143a-43f2-b74d-b140f3d93490",
"set": "ovnt",
"set_name": "Vintage Championship",
"set_type": "memorabilia",
"set_uri": "https://api.scryfall.com/sets/c6a6b61b-143a-43f2-b74d-b140f3d93490",
"set_search_uri": "https://api.scryfall.com/cards/search?order=set&q=e%3Aovnt&unique=prints",
"scryfall_set_uri": "https://scryfall.com/sets/ovnt?utm_source=api",
"rulings_uri": "https://api.scryfall.com/cards/f5d24a5b-c950-4fd9-99e6-a4b979d915b3/rulings",
"prints_search_uri": "https://api.scryfall.com/cards/search?order=released&q=oracleid%3A5089ec1a-f881-4d55-af14-5d996171203b&unique=prints",
"collector_number": "2023NA",
"digital": false,
"rarity": "special",
"flavor_text": "2023 North America\nVintage Championship",
"card_back_id": "0aeebaf5-8c7d-4636-9e82-8c27447861f7",
"artist": "Scott M. Fischer",
"artist_ids": [
"23b0cf43-3e43-44c6-8329-96446eca5bce"
],
"illustration_id": "4bc3f69f-66b6-4a6f-8b55-09df0ea4cb89",
"border_color": "black",
"frame": "2015",
"security_stamp": "oval",
"full_art": false,
"textless": false,
"booster": false,
"story_spotlight": false,
"prices": {
"usd": null,
"usd_foil": null,
"usd_etched": null,
"eur": null,
"eur_foil": null,
"tix": null
},
"related_uris": {
"tcgplayer_infinite_articles": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Darticle%26game%3Dmagic%26q%3DBlack%2BLotus",
"tcgplayer_infinite_decks": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Ddeck%26game%3Dmagic%26q%3DBlack%2BLotus",
"edhrec": "https://edhrec.com/route/?cc=Black+Lotus"
},
"purchase_uris": {
"tcgplayer": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&u=https%3A%2F%2Fwww.tcgplayer.com%2Fsearch%2Fmagic%2Fproduct%3FproductLineName%3Dmagic%26q%3DBlack%2BLotus%26view%3Dgrid",
"cardmarket": "https://www.cardmarket.com/en/Magic/Products/Search?referrer=scryfall&searchString=Black+Lotus&utm_campaign=card_prices&utm_medium=text&utm_source=scryfall",
"cardhoarder": "https://www.cardhoarder.com/cards?affiliate_id=scryfall&data%5Bsearch%5D=Black+Lotus&ref=card-profile&utm_campaign=affiliate&utm_medium=card&utm_source=scryfall"
}
}

View File

@@ -0,0 +1,122 @@
{
"object": "card",
"id": "90f17b85-a866-48e8-aae0-55330109550e",
"oracle_id": "b0d1c34c-30f1-4c07-9527-38b49231eb9f",
"multiverse_ids": [
74257
],
"tcgplayer_id": 37883,
"cardmarket_id": 14779,
"name": "Little Girl",
"lang": "en",
"released_at": "2004-11-19",
"uri": "https://api.scryfall.com/cards/90f17b85-a866-48e8-aae0-55330109550e",
"scryfall_uri": "https://scryfall.com/card/unh/16/little-girl?utm_source=api",
"layout": "normal",
"highres_image": true,
"image_status": "highres_scan",
"image_uris": {
"small": "https://cards.scryfall.io/small/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.jpg?1562488879",
"normal": "https://cards.scryfall.io/normal/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.jpg?1562488879",
"large": "https://cards.scryfall.io/large/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.jpg?1562488879",
"png": "https://cards.scryfall.io/png/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.png?1562488879",
"art_crop": "https://cards.scryfall.io/art_crop/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.jpg?1562488879",
"border_crop": "https://cards.scryfall.io/border_crop/front/9/0/90f17b85-a866-48e8-aae0-55330109550e.jpg?1562488879"
},
"mana_cost": "{HW}",
"cmc": 0.5,
"type_line": "Creature — Human Child",
"oracle_text": "",
"power": ".5",
"toughness": ".5",
"colors": [
"W"
],
"color_identity": [
"W"
],
"keywords": [],
"legalities": {
"standard": "not_legal",
"future": "not_legal",
"historic": "not_legal",
"timeless": "not_legal",
"gladiator": "not_legal",
"pioneer": "not_legal",
"explorer": "not_legal",
"modern": "not_legal",
"legacy": "not_legal",
"pauper": "not_legal",
"vintage": "not_legal",
"penny": "not_legal",
"commander": "not_legal",
"oathbreaker": "not_legal",
"standardbrawl": "not_legal",
"brawl": "not_legal",
"alchemy": "not_legal",
"paupercommander": "not_legal",
"duel": "not_legal",
"oldschool": "not_legal",
"premodern": "not_legal",
"predh": "not_legal"
},
"games": [
"paper"
],
"reserved": false,
"foil": true,
"nonfoil": true,
"finishes": [
"nonfoil",
"foil"
],
"oversized": false,
"promo": false,
"reprint": false,
"variation": false,
"set_id": "4c8bc76a-05a5-43db-aaf0-34deb347b871",
"set": "unh",
"set_name": "Unhinged",
"set_type": "funny",
"set_uri": "https://api.scryfall.com/sets/4c8bc76a-05a5-43db-aaf0-34deb347b871",
"set_search_uri": "https://api.scryfall.com/cards/search?order=set&q=e%3Aunh&unique=prints",
"scryfall_set_uri": "https://scryfall.com/sets/unh?utm_source=api",
"rulings_uri": "https://api.scryfall.com/cards/90f17b85-a866-48e8-aae0-55330109550e/rulings",
"prints_search_uri": "https://api.scryfall.com/cards/search?order=released&q=oracleid%3Ab0d1c34c-30f1-4c07-9527-38b49231eb9f&unique=prints",
"collector_number": "16",
"digital": false,
"rarity": "common",
"flavor_text": "In the future, she may be a distinguished leader, a great scholar, or a decorated hero. These days all she does is pee the bed.",
"card_back_id": "0aeebaf5-8c7d-4636-9e82-8c27447861f7",
"artist": "Rebecca Guay",
"artist_ids": [
"f8f662fa-d597-46a3-afb2-91d6e13243e2"
],
"illustration_id": "fa376327-cd38-4f28-a8ab-7f61cf35a455",
"border_color": "silver",
"frame": "2003",
"full_art": false,
"textless": false,
"booster": true,
"story_spotlight": false,
"prices": {
"usd": "0.29",
"usd_foil": "16.25",
"usd_etched": null,
"eur": "0.29",
"eur_foil": "12.69",
"tix": null
},
"related_uris": {
"gatherer": "https://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=74257&printed=false",
"tcgplayer_infinite_articles": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Darticle%26game%3Dmagic%26q%3DLittle%2BGirl",
"tcgplayer_infinite_decks": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Ddeck%26game%3Dmagic%26q%3DLittle%2BGirl",
"edhrec": "https://edhrec.com/route/?cc=Little+Girl"
},
"purchase_uris": {
"tcgplayer": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&u=https%3A%2F%2Fwww.tcgplayer.com%2Fproduct%2F37883%3Fpage%3D1",
"cardmarket": "https://www.cardmarket.com/en/Magic/Products/Singles/Unhinged/Little-Girl?referrer=scryfall&utm_campaign=card_prices&utm_medium=text&utm_source=scryfall",
"cardhoarder": "https://www.cardhoarder.com/cards?affiliate_id=scryfall&data%5Bsearch%5D=Little+Girl&ref=card-profile&utm_campaign=affiliate&utm_medium=card&utm_source=scryfall"
}
}

View File

@@ -0,0 +1,142 @@
{
"object": "card",
"id": "7b3f0e26-7784-452d-acc8-9f7181e0f7d5",
"oracle_id": "c1fc5923-c3cd-448a-98d1-c154661c2812",
"multiverse_ids": [
615951
],
"mtgo_id": 109062,
"tcgplayer_id": 495791,
"cardmarket_id": 710527,
"name": "Nissa, Resurgent Animist",
"lang": "en",
"released_at": "2023-05-12",
"uri": "https://api.scryfall.com/cards/7b3f0e26-7784-452d-acc8-9f7181e0f7d5",
"scryfall_uri": "https://scryfall.com/card/mat/162/nissa-resurgent-animist?utm_source=api",
"layout": "normal",
"highres_image": true,
"image_status": "highres_scan",
"image_uris": {
"small": "https://cards.scryfall.io/small/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.jpg?1684341884",
"normal": "https://cards.scryfall.io/normal/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.jpg?1684341884",
"large": "https://cards.scryfall.io/large/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.jpg?1684341884",
"png": "https://cards.scryfall.io/png/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.png?1684341884",
"art_crop": "https://cards.scryfall.io/art_crop/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.jpg?1684341884",
"border_crop": "https://cards.scryfall.io/border_crop/front/7/b/7b3f0e26-7784-452d-acc8-9f7181e0f7d5.jpg?1684341884"
},
"mana_cost": "{2}{G}",
"cmc": 3,
"type_line": "Legendary Creature — Elf Scout",
"oracle_text": "Landfall — Whenever a land you control enters, add one mana of any color. Then if this is the second time this ability has resolved this turn, reveal cards from the top of your library until you reveal an Elf or Elemental card. Put that card into your hand and the rest on the bottom of your library in a random order.",
"power": "3",
"toughness": "3",
"colors": [
"G"
],
"color_identity": [
"G"
],
"keywords": [
"Landfall"
],
"produced_mana": [
"B",
"G",
"R",
"U",
"W"
],
"legalities": {
"standard": "legal",
"future": "legal",
"historic": "legal",
"timeless": "legal",
"gladiator": "legal",
"pioneer": "legal",
"explorer": "legal",
"modern": "legal",
"legacy": "legal",
"pauper": "not_legal",
"vintage": "legal",
"penny": "not_legal",
"commander": "legal",
"oathbreaker": "legal",
"standardbrawl": "legal",
"brawl": "legal",
"alchemy": "not_legal",
"paupercommander": "not_legal",
"duel": "legal",
"oldschool": "not_legal",
"premodern": "not_legal",
"predh": "not_legal"
},
"games": [
"paper",
"arena",
"mtgo"
],
"reserved": false,
"foil": true,
"nonfoil": true,
"finishes": [
"nonfoil",
"foil"
],
"oversized": false,
"promo": false,
"reprint": false,
"variation": false,
"set_id": "6727e43d-31b6-45b0-ae05-7a811ba72f70",
"set": "mat",
"set_name": "March of the Machine: The Aftermath",
"set_type": "expansion",
"set_uri": "https://api.scryfall.com/sets/6727e43d-31b6-45b0-ae05-7a811ba72f70",
"set_search_uri": "https://api.scryfall.com/cards/search?order=set&q=e%3Amat&unique=prints",
"scryfall_set_uri": "https://scryfall.com/sets/mat?utm_source=api",
"rulings_uri": "https://api.scryfall.com/cards/7b3f0e26-7784-452d-acc8-9f7181e0f7d5/rulings",
"prints_search_uri": "https://api.scryfall.com/cards/search?order=released&q=oracleid%3Ac1fc5923-c3cd-448a-98d1-c154661c2812&unique=prints",
"collector_number": "162",
"digital": false,
"rarity": "mythic",
"watermark": "desparked",
"card_back_id": "0aeebaf5-8c7d-4636-9e82-8c27447861f7",
"artist": "Tuan Duong Chu",
"artist_ids": [
"d84246f9-a536-485f-a21d-a237302ed100"
],
"illustration_id": "66ab8b7b-9e90-4db9-8d5e-10629a4acce4",
"border_color": "black",
"frame": "2015",
"frame_effects": [
"legendary",
"extendedart"
],
"security_stamp": "oval",
"full_art": false,
"textless": false,
"booster": false,
"story_spotlight": false,
"promo_types": [
"boosterfun"
],
"edhrec_rank": 2163,
"prices": {
"usd": "24.96",
"usd_foil": "32.13",
"usd_etched": null,
"eur": "27.94",
"eur_foil": "35.15",
"tix": "0.99"
},
"related_uris": {
"gatherer": "https://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=615951&printed=false",
"tcgplayer_infinite_articles": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Darticle%26game%3Dmagic%26q%3DNissa%252C%2BResurgent%2BAnimist",
"tcgplayer_infinite_decks": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&trafcat=infinite&u=https%3A%2F%2Finfinite.tcgplayer.com%2Fsearch%3FcontentMode%3Ddeck%26game%3Dmagic%26q%3DNissa%252C%2BResurgent%2BAnimist",
"edhrec": "https://edhrec.com/route/?cc=Nissa%2C+Resurgent+Animist"
},
"purchase_uris": {
"tcgplayer": "https://partner.tcgplayer.com/c/4931599/1830156/21018?subId1=api&u=https%3A%2F%2Fwww.tcgplayer.com%2Fproduct%2F495791%3Fpage%3D1",
"cardmarket": "https://www.cardmarket.com/en/Magic/Products/Singles/MoM-TA-E/Nissa-Resurgent-Animist-V3?referrer=scryfall&utm_campaign=card_prices&utm_medium=text&utm_source=scryfall",
"cardhoarder": "https://www.cardhoarder.com/cards/109062?affiliate_id=scryfall&ref=card-profile&utm_campaign=affiliate&utm_medium=card&utm_source=scryfall"
}
}