scryfall/src/lib.rs

183 lines
4.6 KiB
Rust
Raw Permalink Normal View History

2017-12-03 22:54:19 -06:00
extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
extern crate reqwest;
#[macro_use] extern crate derive_error;
use std::collections::HashMap;
use std::io::Read;
2017-12-03 23:56:35 -06:00
use std::fmt;
use std::fmt::{Display, Formatter};
2017-12-03 22:54:19 -06:00
pub struct Scryfall {}
impl Scryfall {
pub fn new() -> Scryfall {
Scryfall {}
}
2017-12-04 00:18:59 -06:00
pub fn search(&self, query: &str, order: Option<&str>, page: i32) -> Result<CardList, Error> {
let mut response = reqwest::get(&format!(
"https://api.scryfall.com/cards/search?q={}&order={}&page={}",
query,
order.unwrap_or("name"),
page
))?;
2017-12-03 22:54:19 -06:00
let mut content = String::new();
response.read_to_string(&mut content);
2017-12-03 23:56:35 -06:00
match serde_json::from_str(&content) {
Ok(list) => Ok(list),
Err(error) => {
match serde_json::from_str(&content) {
Ok(api_error) => Err(Error::API(api_error)),
Err(_) => Err(Error::Parse(error))
}
}
}
2017-12-03 22:54:19 -06:00
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CardList {
pub data: Vec<Card>,
pub has_more: bool,
pub next_page: Option<String>,
pub total_cards: u32,
pub warnings: Option<Vec<String>>
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Card {
pub id: String,
pub multiverse_ids: Vec<u32>,
pub mtgo_id: Option<u32>,
pub mtgo_foil_id: Option<u32>,
pub uri: String,
pub scryfall_uri: String,
pub rulings_uri: String,
pub name: String,
pub layout: String,
pub cmc: f32,
pub type_line: Option<String>,
2017-12-03 22:54:19 -06:00
pub oracle_text: Option<String>,
pub mana_cost: Option<String>,
2017-12-03 22:54:19 -06:00
pub power: Option<String>,
pub toughness: Option<String>,
pub loyalty: Option<String>,
pub life_modifier: Option<String>,
pub hand_modifier: Option<String>,
pub colors: Option<Colors>,
2017-12-03 22:54:19 -06:00
pub color_indicator: Option<Colors>,
pub color_identity: Colors,
pub all_parts: Option<Vec<RelatedCard>>,
pub card_faces: Option<Vec<CardFace>>,
pub legalities: HashMap<String, String>,
pub reserved: bool,
pub edhrec_rank: Option<u32>,
pub set: String,
pub set_name: String,
pub collector_number: String,
pub set_search_uri: String,
pub scryfall_set_uri: String,
pub image_uris: Option<HashMap<String, String>>,
pub highres_image: bool,
pub reprint: bool,
pub digital: bool,
pub rarity: String,
pub flavor_text: Option<String>,
pub artist: Option<String>,
pub frame: String,
pub full_art: bool,
pub watermark: Option<String>,
pub border_color: String,
pub story_spotlight_number: Option<u32>,
pub story_spotlight_uri: Option<String>,
pub timeshifted: bool,
pub colorshifted: bool,
pub futureshifted: bool
}
type Colors = Vec<String>;
#[derive(Serialize, Deserialize, Debug)]
pub struct RelatedCard {
pub id: String,
pub name: String,
pub uri: String
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CardFace {
pub name: String,
pub type_line: String,
pub oracle_text: Option<String>,
pub mana_cost: String,
pub colors: Option<Colors>,
2017-12-03 22:54:19 -06:00
pub color_indicator: Option<Colors>,
pub power: Option<String>,
pub toughness: Option<String>,
pub loyalty: Option<String>,
pub flavor_text: Option<String>,
pub image_uris: Option<HashMap<String, String>>
}
#[derive(Debug, Error)]
pub enum Error {
/// HTTP request failed
HTTP(reqwest::Error),
/// Failed to parse
2017-12-03 23:56:35 -06:00
Parse(serde_json::Error),
/// Error from API
API(APIError)
}
#[derive(Serialize, Deserialize, Debug)]
pub struct APIError {
pub status: i32,
pub code: String,
pub details: String,
pub error_type: Option<String>,
pub warnings: Option<Vec<String>>
}
impl std::error::Error for APIError {
fn description(&self) -> &str {
&self.details
}
fn cause(&self) -> Option<&std::error::Error> {
None
}
}
impl Display for APIError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.details)
}
2017-12-03 22:54:19 -06:00
}
#[cfg(test)]
mod tests {
2017-12-03 23:12:24 -06:00
use serde_json;
use *;
2017-12-03 22:54:19 -06:00
#[test]
2017-12-03 23:12:24 -06:00
fn deserialize_is_funny() {
let list: CardList = serde_json::from_str(include_str!("../test_data/is_funny.json")).unwrap();
2017-12-03 22:54:19 -06:00
}
2017-12-03 23:32:18 -06:00
#[test]
fn deserialize_o_transform() {
let list: CardList = serde_json::from_str(include_str!("../test_data/o_transform.json")).unwrap();
}
2017-12-03 23:39:14 -06:00
#[test]
fn deserialize_t_plane() {
let list: CardList = serde_json::from_str(include_str!("../test_data/t_plane.json")).unwrap();
}
2017-12-03 22:54:19 -06:00
}