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}