use crate::api::card::filter::CardFilter;
use crate::api::card::filtertypes::CardResponseField;
use crate::api::error::MtgApiErrorKind;
use failure::Error;
use failure::ResultExt;
use reqwest::Client;
use crate::api::response::ApiResponse;
use crate::model::card::CardDetail;
use std::rc::Weak;
use crate::api::util;
pub struct CardApi {
client: Weak<Client>,
url: String,
}
impl CardApi {
pub(crate) fn new(client: Weak<Client>, url: String) -> CardApi {
CardApi { client, url }
}
#[allow(dead_code)]
pub fn all(&self) -> Box<AllCardsRequest> {
AllCardsRequest::new(self.client.clone(), &self.url, 100)
}
#[allow(dead_code)]
pub fn all_filtered(&self, filter: CardFilter) -> Box<AllCardsRequest> {
AllCardsRequest::new_filtered(self.client.clone(), &self.url, 100, filter)
}
pub async fn find(&self, id: u32) -> Result<ApiResponse<CardDetail>, Error> {
let url = [&self.url, "/cards/", &id.to_string()].join("");
let mut response = util::send_response(&url, &self.client).await?;
let headers = std::mem::take(response.headers_mut());
let body = response.text().await.context(MtgApiErrorKind::BodyReadError)?;
let card = util::retrieve_card_from_body(&body)?;
Ok(ApiResponse::new(*card, headers))
}
}
#[allow(dead_code)]
pub struct AllCardsRequest {
page: u32,
client: Weak<Client>,
url: String,
filter: CardFilter,
order_by: CardResponseField,
page_size: u32,
}
impl AllCardsRequest {
fn new(client: Weak<Client>, api_url: &str, page_size: u32) -> Box<AllCardsRequest> {
let url = [api_url, "cards"].join("/");
Box::new(AllCardsRequest {
page: 1,
client,
url,
filter: CardFilter(String::new()),
page_size,
order_by: CardResponseField::Name,
})
}
fn new_filtered(
client: Weak<Client>,
api_url: &str,
page_size: u32,
filter: CardFilter,
) -> Box<AllCardsRequest> {
let url = [api_url, "cards"].join("/");
Box::new(AllCardsRequest {
page: 1,
client,
url,
filter,
page_size,
order_by: CardResponseField::Name,
})
}
#[allow(dead_code)]
pub async fn next_page(&mut self) -> Result<ApiResponse<Vec<CardDetail>>, Error> {
let url = self.create_filtered_url();
let mut response = util::send_response(&url, &self.client).await?;
self.page += 1;
let headers = std::mem::take(response.headers_mut());
let body = response.text().await.context(MtgApiErrorKind::CardBodyParseError)?;
let cards = util::retrieve_cards_from_body(&body)?;
Ok(ApiResponse::new(cards, headers))
}
#[allow(dead_code)]
pub fn order_by(&mut self, field: CardResponseField) {
self.order_by = field;
}
#[allow(dead_code)]
pub fn set_page(&mut self, page: u32) {
self.page = page;
}
#[allow(dead_code)]
pub fn set_page_size(&mut self, size: u32) {
self.page_size = size;
}
fn create_filtered_url(&self) -> String {
let page_filter = ["page", self.page.to_string().as_str()].join("=");
let paged_filter = if self.filter.0.is_empty() {
[self.filter.0.as_str(), &page_filter].join("")
} else {
[self.filter.0.as_str(), &page_filter].join("&")
};
let page_size_filter = ["pageSize", &self.page_size.to_string()].join("=");
let paged_filter_sized = [paged_filter, page_size_filter].join("&");
[self.url.as_str(), paged_filter_sized.as_str()].join("?")
}
}