Skip to content

Commit

Permalink
Make most structs non-exaustive and deny missing fields in tests to k…
Browse files Browse the repository at this point in the history
…eep the structs up to date
  • Loading branch information
mendess committed Jul 14, 2024
1 parent 860e77d commit 231b505
Show file tree
Hide file tree
Showing 27 changed files with 171 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "scryfall"
version = "0.16.3"
version = "0.17.0"
authors = ["Mendess2526 <[email protected]>"]
edition = "2018"
description = "A wrapper around the scryfall magic the gathering api"
Expand Down
28 changes: 27 additions & 1 deletion src/bulk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ use crate::util::BULK_DATA_URL;
/// Bulk data is only collected once every 12 hours. You can use the card API
/// methods to retrieve fresh objects instead.
#[derive(Deserialize, Debug, Clone)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct BulkDataFile<T> {
/// A unique ID for this bulk item.
pub id: Uuid,
Expand Down Expand Up @@ -87,6 +89,13 @@ pub struct BulkDataFile<T> {
/// The Content-Encoding encoding that will be used to transmit this file
/// when you download it.
pub content_encoding: String,

/// The byte size of the bulk file.
pub size: usize,

#[cfg(test)]
#[serde(rename = "object")]
_object: String,
}

impl<T: DeserializeOwned> BulkDataFile<T> {
Expand Down Expand Up @@ -255,7 +264,24 @@ mod tests {
.block_on(super::all_cards())
.expect("Couldn't get the bulk object")
{
card.unwrap();
let card = card.unwrap();
for p in card.promo_types {
eprintln!("{p}");
}
if let Some(defense) = card.defense {
eprintln!("d: {} {defense}", card.name);
}
for face in card.card_faces.unwrap_or_default() {
if let Some(defense) = face.defense {
eprintln!("d: {} {defense}", card.name);
}
}

if let Some(lights) = card.attraction_lights {
for l in lights {
eprintln!("l: {l}");
}
}
}
}

Expand Down
39 changes: 39 additions & 0 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
mod border_color;
mod card_faces;
mod color;
mod finishes;
mod frame;
mod frame_effect;
mod game;
Expand All @@ -17,11 +18,14 @@ mod price;
mod produced_mana;
mod rarity;
mod related_card;
mod security_stamp;

use std::collections::hash_map::HashMap;
use std::ops::{Index, IndexMut};

use chrono::NaiveDate;
use finishes::Finishes;
use security_stamp::SecurityStamp;
use serde::{Deserialize, Serialize};
use url::Url;
use uuid::Uuid;
Expand Down Expand Up @@ -164,6 +168,7 @@ impl IndexMut<Format> for CardLegality {
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[cfg_attr(test, serde(deny_unknown_fields))]
/// Scryfall produces multiple sizes of images and image crops for each Card object. Links to these
/// images are available in each Card objects’ image_uris properties.
///
Expand Down Expand Up @@ -223,6 +228,8 @@ pub struct ImageUris {
///
/// For more details, see the [official documentation](https://scryfall.com/docs/api/cards).
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct Card {
// region Core Card Fields
// =======================
Expand Down Expand Up @@ -255,6 +262,9 @@ pub struct Card {
/// This card’s ID on TCGplayer’s API, also known as the `productId`.
pub tcgplayer_id: Option<usize>,

/// This card’s ID on TCGplayer’s API, for its etched version if that version is a separate product.
pub tcgplayer_etched_id: Option<usize>,

/// This card’s ID on Cardmarket’s API, also known as the `idProduct`.
pub cardmarket_id: Option<usize>,

Expand Down Expand Up @@ -366,6 +376,12 @@ pub struct Card {

/// The type line of this card.
pub type_line: Option<String>,

/// This card’s rank/popularity on Penny Dreadful. Not all cards are ranked.
pub penny_rank: Option<u64>,

/// This face’s defense, if any.
pub defense: Option<String>,
// =========================
// endregion Gameplay Fields
//
Expand All @@ -375,6 +391,9 @@ pub struct Card {
/// have this field yet.
pub artist: Option<String>,

/// The IDs of the artists that illustrated this card. Newly spoiled cards may not have this field yet.
pub artist_ids: Option<Vec<Uuid>>,

/// Whether this card is found in boosters.
pub booster: bool,

Expand Down Expand Up @@ -486,6 +505,9 @@ pub struct Card {
/// This card’s set code.
pub set: SetCode,

/// The scryfall id of the set it belongs to.
pub set_id: Uuid,

/// True if this card is a Story Spotlight.
pub story_spotlight: bool,

Expand All @@ -504,8 +526,25 @@ pub struct Card {
/// Information about when and where the card was originally previewed.
#[serde(default)]
pub preview: Preview,

/// The finishes the card can come in.
pub finishes: Vec<Finishes>,

/// The security stamp on this card, if any.
#[serde(default)]
pub security_stamp: Option<SecurityStamp>,

/// An array of strings describing what categories of promo cards this card falls into.
#[serde(default)]
pub promo_types: Vec<String>,

/// The lit Unfinity attractions lights on this card, if any.
pub attraction_lights: Option<Vec<u8>>,
/* ======================
* endregion Print Fields */
#[cfg(test)]
#[serde(rename = "object")]
_object: String,
}

impl Card {
Expand Down
1 change: 1 addition & 0 deletions src/card/border_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};

/// Enum defining the colors a mtg card border can have.
#[derive(Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[allow(missing_docs)]
#[non_exhaustive]
Expand Down
25 changes: 24 additions & 1 deletion src/card/card_faces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ use uuid::Uuid;
use crate::card::Color;
use crate::card::ImageUris;

use super::Layout;

/// Multiface cards have a card_faces property containing at least two Card Face
/// objects.
///
/// ---
///
/// For more information, refer to the [official docs](https://scryfall.com/docs/api/cards#card-face-objects).
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
#[non_exhaustive]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct CardFace {
/// The name of the illustrator of this card face. Newly spoiled cards may
/// not have this field yet.
Expand All @@ -23,6 +27,9 @@ pub struct CardFace {
/// of this card.
pub colors: Option<Vec<Color>>,

/// The mana value of this particular face, if the card is reversible.
pub cmc: Option<f32>,

/// The flavor text printed on this face, if any.
pub flavor_text: Option<String>,

Expand Down Expand Up @@ -73,4 +80,20 @@ pub struct CardFace {

/// The watermark on this particulary card face, if any.
pub watermark: Option<String>,

/// The ID of the illustrator of this card face. Newly spoiled cards may not have this field yet.
pub artist_id: Option<Uuid>,

/// The just-for-fun name printed on the card (such as for Godzilla series cards).
pub flavor_name: Option<String>,

/// This face’s defense, if any.
pub defense: Option<String>,

/// The layout of this card face, if the card is reversible.
pub layout: Option<Layout>,

#[cfg(test)]
#[serde(rename = "object")]
_object: String,
}
1 change: 1 addition & 0 deletions src/card/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl fmt::Display for Color {
/// the `search` module as a
/// [`ColorValue`][crate::search::param::value::ColorValue].
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Colors(u8);

macro_rules! color_consts {
Expand Down
15 changes: 15 additions & 0 deletions src/card/finishes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};

/// The finish the card can come in.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum Finishes {
/// Nonfoil.
Nonfoil,
/// Foil.
Foil,
/// Etched foil.
Etched,
}
2 changes: 2 additions & 0 deletions src/card/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use serde::{Deserialize, Serialize};
///
/// [Official docs](https://scryfall.com/docs/api/layouts#frames)
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[non_exhaustive]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub enum Frame {
/// The original Magic card frame, starting from Limited Edition Alpha.
#[serde(rename = "1993")]
Expand Down
1 change: 1 addition & 0 deletions src/card/frame_effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
///
/// [Official docs](https://scryfall.com/docs/api/layouts#frame-effects)
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum FrameEffect {
Expand Down
1 change: 1 addition & 0 deletions src/card/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};

/// Enum defining the exiting platforms on with a magic card can exist.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[allow(missing_docs)]
#[non_exhaustive]
Expand Down
1 change: 1 addition & 0 deletions src/card/image_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
/// computer-readable value of the image’s state using the image_status field
/// on card objects.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
pub enum ImageStatus {
/// The card has no image, or the image is being processed.
Expand Down
1 change: 1 addition & 0 deletions src/card/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize};
///
/// [Official docs](https://scryfall.com/docs/api/layouts#layout)
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Layout {
Expand Down
1 change: 1 addition & 0 deletions src/card/legality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};

/// Enum describing the 4 states of legality a card can have.
#[derive(Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[allow(missing_docs)]
pub enum Legality {
Expand Down
1 change: 1 addition & 0 deletions src/card/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use url::Url;

/// Struct describing card preview information.
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Hash, Debug, Default)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Preview {
/// The date this card was previewed.
pub previewed_at: Option<NaiveDate>,
Expand Down
3 changes: 3 additions & 0 deletions src/card/price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ use serde::{Deserialize, Serialize};

/// Struct defining a price object containing data in various currencies.
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Hash, Debug, Default)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[allow(missing_docs)]
#[non_exhaustive]
pub struct Price {
pub usd: Option<String>,
pub usd_foil: Option<String>,
pub eur: Option<String>,
pub eur_foil: Option<String>,
pub tix: Option<String>,
pub usd_etched: Option<String>,
}

impl Price {
Expand Down
2 changes: 2 additions & 0 deletions src/card/produced_mana.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(untagged)]
/// A type of mana a card can produce
pub enum ProducedMana {
Expand All @@ -22,6 +23,7 @@ impl ProducedMana {

/// Kinds of mana only produced in unfinity
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub enum UnfinityMana {
/// Some sticker sheets have stickers that give creatures the ability to generate 2
/// colorless mana, for some reason wizards used the old templating
Expand Down
2 changes: 2 additions & 0 deletions src/card/rarity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use serde::{Deserialize, Serialize};
/// For the purposes of sorting and comparison, `Special` is considered above
/// `Rare` and below `Mythic`, and `Bonus` is the rarest, above `Mythic.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Rarity {
/// Black set symbol.
Common,
Expand Down
7 changes: 7 additions & 0 deletions src/card/related_card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::uri::Uri;
///
/// For more information, refer to the [official docs](https://scryfall.com/api/cards#related-card-objects).
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct RelatedCard {
/// An unique ID for this card in Scryfall’s database.
pub id: Uuid,
Expand All @@ -25,10 +27,15 @@ pub struct RelatedCard {

/// The name of this particular related card.
pub uri: Uri<Card>,

#[cfg(test)]
#[serde(rename = "object")]
_object: String,
}

/// The kind of related card.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Component {
Expand Down
15 changes: 15 additions & 0 deletions src/card/security_stamp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};

/// The security stamp on this card, if any.
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum SecurityStamp {
Oval,
Triangle,
Acorn,
Circle,
Arena,
Heart,
}
1 change: 1 addition & 0 deletions src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::util::CATALOG_URL;
/// Magic software and understanding possible values for a field on Card
/// objects.
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Catalog {
/// A link to the current catalog on Scryfall’s API.
pub uri: Uri<Catalog>,
Expand Down
Loading

0 comments on commit 231b505

Please sign in to comment.