pokemon_tcg_api_client/builder/
pokemon.rs

1use std::collections::HashMap;
2
3use crate::pokemon_api_client::api_client::CardId;
4
5use super::{Ordering, QueryBuilder};
6
7/// Query builder for pokemon card api requests.
8#[derive(Clone)]
9pub struct PokemonQueryBuilder {
10    filters: HashMap<String, String>,
11    page: Option<u32>,
12    page_size: Option<u8>,
13    order_by: Vec<Ordering>,
14    select_fields: Vec<String>,
15}
16
17impl PokemonQueryBuilder {
18    /// Sets the page size of the query builder.
19    ///
20    /// # Arguments
21    ///
22    /// * `size` - The size of the page.
23    #[must_use]
24    pub fn with_page_size(self, size: u8) -> Self {
25        let mut new = self.clone();
26        new.page_size = Some(size);
27        new
28    }
29
30    /// Sets the page from which it should get the results.
31    ///
32    /// # Arguments
33    ///
34    /// * `page` - The number of the page to select.
35    #[must_use]
36    pub fn with_page(self, page: u32) -> Self {
37        let mut new = self.clone();
38        new.page = Some(page);
39        new
40    }
41
42    /// Adds a parameter to the ordering list.
43    ///
44    /// # Arguments
45    ///
46    /// * `ordering` - A fields to order by in the data.
47    #[must_use]
48    pub fn add_ordering(self, ordering: Ordering) -> Self {
49        let mut new = self.clone();
50        new.order_by.push(ordering);
51        new
52    }
53
54    /// Adds a value to select from the requested data.
55    /// The returned data will only contain values with those fields.
56    ///
57    /// # Arguments
58    ///
59    /// * `field` - A field to at to the query.
60    #[must_use]
61    pub fn add_select(self, field: &str) -> Self {
62        let mut new = self.clone();
63        new.select_fields.push(String::from(field));
64        self
65    }
66
67    /// Adds a id to the query parameter, if used more than once it turns into an OR.
68    ///
69    /// # Arguments
70    ///
71    /// * `id` - The id of the pokemon card you want to filter for.
72    #[must_use]
73    pub fn add_id(self, id: &CardId) -> Self {
74        self.add_or_update_filter("id", &id.0)
75    }
76
77    /// Adds a card name to the query parameter, if used more than once it turns into an OR.
78    ///
79    /// # Arguments
80    ///
81    /// * `name` - The name of the pokemon card you want to filter for.
82    #[must_use]
83    pub fn add_name(self, name: &str) -> Self {
84        self.add_or_update_filter("name", name)
85    }
86
87    /// Adds a sub type to the query parameter, if used more than once it turns into an OR.
88    ///
89    /// # Arguments
90    ///
91    /// * `sub_types` - The sub type you want to query for.
92    #[must_use]
93    pub fn add_sub_types(self, sub_type: &str) -> Self {
94        self.add_or_update_filter("subtypes", sub_type)
95    }
96
97    /// Adds a hp range to the query parameter. Can be inclusive or exclusive.
98    ///
99    /// # Arguments
100    ///
101    /// * `low_value` - The low value of the hp range.
102    /// * `high_value` - The high value of the hp range.
103    /// * `is_inclusive` - Sets whether the range is inclusive.
104    #[must_use]
105    pub fn add_hp_range(self, low_value: &str, high_value: &str, is_inclusive: bool) -> Self {
106        if is_inclusive {
107            return self.add_or_update_filter("hp", &format!("[{low_value} TO {high_value}]"));
108        }
109
110        self.add_or_update_filter("hp", &format!("{{{low_value} TO {high_value}}}"))
111    }
112
113    /// Adds a type to the query parameter.
114    ///
115    /// # Arguments
116    ///
117    /// * `types` - The type of to add to the query.
118    #[must_use]
119    pub fn add_types(self, types: &str) -> Self {
120        self.add_or_update_filter("types", types)
121    }
122
123    /// Adds a pokemon name the searched pokemon evolves from to the query parameter.
124    ///
125    /// # Arguments
126    ///
127    /// * `evolves_from` - The evolved from pokemon to add to the query.
128    #[must_use]
129    pub fn add_evolves_from(self, evolves_from: &str) -> Self {
130        self.add_or_update_filter("evolvesFrom", evolves_from)
131    }
132
133    /// Adds a pokemon name the searched pokemon evolves tp to the query parameter.
134    ///
135    /// # Arguments
136    ///
137    /// * `evolves_to` - The evolved to pokemon to add to the query.
138    #[must_use]
139    pub fn add_evolves_to(self, evolves_to: &str) -> Self {
140        self.add_or_update_filter("evolvesTo", evolves_to)
141    }
142
143    /// Adds a attack cost range to the query parameter. Can be inclusive or exclusive.
144    ///
145    /// # Arguments
146    ///
147    /// * `low_value` - The low value of the attack range.
148    /// * `high_value` - The high value of the attack range.
149    /// * `is_inclusive` - Sets whether the range is inclusive.
150    #[must_use]
151    pub fn add_attack_cost_range(
152        self,
153        low_value: &str,
154        high_value: &str,
155        is_inclusive: bool,
156    ) -> Self {
157        if is_inclusive {
158            return self.add_or_update_filter(
159                "attacks.convertedEnergyCost",
160                &format!("[{low_value} TO {high_value}]"),
161            );
162        }
163
164        self.add_or_update_filter(
165            "attacks.convertedEnergyCost",
166            &format!("{{{low_value} TO {high_value}}}"),
167        )
168    }
169
170    /// Adds a set series to the query parameter, if used more than once it turns into an OR.
171    /// Look at Pokemon TCG Api wiki <https://docs.pokemontcg.io/api-reference/cards/search-cards/> for a documentation about wildcards.
172    ///
173    /// # Arguments
174    ///
175    /// * `set_series` - The name of set series of the card you want to query for.
176    #[must_use]
177    pub fn add_set_name(self, set_name: &str) -> Self {
178        self.add_or_update_filter("set.series", set_name)
179    }
180
181    /// Adds a rarity to the query.
182    ///
183    /// # Arguments
184    ///
185    /// * `rarity` - The rarity of the pokemon card.
186    #[must_use]
187    pub fn add_rarity(self, rarity: &str) -> Self {
188        self.add_or_update_filter("rarity", rarity)
189    }
190
191    fn add_or_update_filter(mut self, key: &str, value: &str) -> Self {
192        if let Some(old_value) = self.filters.get_mut(key) {
193            *old_value = format!("{old_value},{value}");
194            return self;
195        }
196
197        self.filters.insert(String::from(key), String::from(value));
198        self
199    }
200}
201
202impl QueryBuilder for PokemonQueryBuilder {
203    fn new() -> Self {
204        PokemonQueryBuilder {
205            filters: HashMap::new(),
206            page: None,
207            page_size: None,
208            order_by: Vec::new(),
209            select_fields: Vec::new(),
210        }
211    }
212
213    fn page(&self) -> Option<u32> {
214        self.page
215    }
216
217    fn page_size(&self) -> Option<u8> {
218        self.page_size
219    }
220
221    fn filters(&self) -> HashMap<String, String> {
222        self.filters.clone()
223    }
224
225    fn order_by(&self) -> Vec<Ordering> {
226        self.order_by.clone()
227    }
228
229    fn select_fields(&self) -> Vec<String> {
230        self.select_fields.clone()
231    }
232}