pokemon_tcg_sdk/
set.rs

1mod images;
2mod legality;
3
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    client::{ApiResult, Client},
8    errors::ClientError,
9};
10
11use self::{images::SetImages, legality::Legality};
12
13/// The Set Object
14/// https://docs.pokemontcg.io/api-reference/sets/set-object
15#[derive(Debug, Clone, Deserialize, Serialize)]
16#[cfg_attr(test, derive(Default))]
17pub struct Set {
18    /// Unique identifier for the object.
19    pub id: String,
20    /// The name of the set.
21    pub name: String,
22    /// The series the set belongs to, like Sword and Shield or Base.
23    pub series: String,
24    /// The number printed on the card that represents the total. This total does not include secret rares.
25    #[serde(alias = "printedTotal")]
26    pub printed_total: usize,
27    /// The total number of cards in the set, including secret rares, alternate art, etc.
28    pub total: usize,
29    /// The legalities of the set. If a given format is not legal, it will not appear in the hash.
30    pub legalities: Legality,
31    /// The code the Pokémon Trading Card Game Online uses to identify a set.
32    #[serde(alias = "ptcgoCode")]
33    pub ptcgo_code: Option<String>,
34    /// The date the set was released (in the USA). Format is YYYY/MM/DD.
35    #[serde(alias = "releaseDate")]
36    pub release_date: String,
37    /// The date and time the set was updated. Format is YYYY/MM/DD HH:MM:SS.
38    #[serde(alias = "updatedAt")]
39    pub updated_at: String,
40    /// Any images associated with the set, such as symbol and logo.
41    pub images: SetImages,
42}
43
44pub struct GetSetRequest {
45    pub id: String,
46}
47
48impl GetSetRequest {
49    pub fn new(id: &str) -> Self {
50        GetSetRequest { id: id.into() }
51    }
52}
53
54pub struct SearchSetsRequest {
55    ///The search query.
56    pub query: Option<String>,
57    /// The page of data to access.
58    pub page: Option<u16>,
59    /// The maximum amount of sets to return. Max of 250.
60    pub page_size: Option<u8>,
61    /// The field(s) to order the results by.
62    pub order_by: Option<String>,
63}
64
65impl SearchSetsRequest {
66    pub fn new(query: &str) -> Self {
67        SearchSetsRequest {
68            query: Some(String::from(query)),
69            page: None,
70            page_size: None,
71            order_by: None,
72        }
73    }
74}
75
76impl Client {
77    /// Fetch the details of a single set.
78    ///
79    /// https://docs.pokemontcg.io/api-reference/sets/get-set
80    pub async fn get_set(&self, request: GetSetRequest) -> Result<Set, ClientError> {
81        let set = self
82            .http_client
83            .get(format!("{}/sets/{}", self.base_url, request.id))
84            .send()
85            .await?
86            .json::<ApiResult<Set>>()
87            .await?;
88
89        Client::parse_response(set)
90    }
91
92    /// Search for one or many sets given a search query.
93    ///
94    /// https://docs.pokemontcg.io/api-reference/sets/search-cards
95    pub async fn search_sets(&self, request: SearchSetsRequest) -> Result<Vec<Set>, ClientError> {
96        let sets = self
97            .http_client
98            .get(format!("{}/sets", self.base_url))
99            .query(&[
100                ("q", request.query),
101                ("page", request.page.map(|p| p.to_string())),
102                ("pageSize", request.page_size.map(|p| p.to_string())),
103                ("orderBy", request.order_by),
104            ])
105            .send()
106            .await?
107            .json::<ApiResult<Vec<Set>>>()
108            .await?;
109
110        Client::parse_response(sets)
111    }
112
113    /// Get all sets (automatically pages through data)
114    pub async fn get_all_sets(&self) -> Result<Vec<Set>, ClientError> {
115        let mut page = 1;
116        let page_size = 250;
117        let mut total_pages: usize = 0;
118        let mut sets: Vec<Set> = vec![];
119
120        loop {
121            let resp = self
122                .http_client
123                .get(format!("{}/sets", self.base_url))
124                .query(&[("page", page)])
125                .send()
126                .await?
127                .json::<ApiResult<Vec<Set>>>()
128                .await?;
129
130            let total_count = if let ApiResult::Ok(ev) = &resp {
131                ev.total_count
132            } else {
133                None
134            };
135
136            match Client::parse_response(resp) {
137                Ok(mut cv) => {
138                    sets.append(&mut cv);
139                    if sets.len() % page_size != 0 {
140                        break;
141                    }
142                    if let Some(tc) = total_count {
143                        total_pages = ((tc / page_size) as f64).ceil() as usize;
144                    }
145
146                    if page > total_pages {
147                        break;
148                    }
149
150                    page += 1;
151                }
152                Err(e) => {
153                    return Err(e);
154                }
155            };
156        }
157
158        Ok(sets)
159    }
160}