kodik_api/countries.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 error::Error,
5 types::{
6 AllStatus, AnimeKind, AnimeStatus, DramaStatus, MaterialDataField, MppaRating, ReleaseType,
7 TranslationType,
8 },
9 util::serialize_into_query_parts,
10 Client,
11};
12
13#[derive(Serialize, Deserialize, Debug, Clone)]
14pub struct CountryResult {
15 // Name of the country
16 pub title: String,
17
18 /// The number of materials with this voice acting
19 pub count: i32,
20}
21
22/// A struct containing countries results and other information about the countries
23#[derive(Deserialize, Debug, Clone)]
24pub struct CountryResponse {
25 pub time: String,
26 pub total: i32,
27 pub prev_page: Option<String>,
28 pub next_page: Option<String>,
29 pub results: Vec<CountryResult>,
30}
31
32#[derive(Deserialize, Debug, Clone)]
33#[serde(untagged)]
34enum CountryResponseUnion {
35 Result(CountryResponse),
36 Error { error: String },
37}
38
39#[derive(Serialize, Deserialize, Debug, Clone)]
40pub enum CountrySort {
41 #[serde(rename = "title")]
42 Title,
43 #[serde(rename = "count")]
44 Count,
45}
46
47#[derive(Debug, Serialize, Clone)]
48pub struct CountryQuery<'a> {
49 /// What field to sort materials by
50 #[serde(skip_serializing_if = "Option::is_none")]
51 sort: Option<CountrySort>,
52
53 /// Maximum number of outputs
54 #[serde(skip_serializing_if = "Option::is_none")]
55 types: Option<&'a [ReleaseType]>,
56
57 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
58 #[serde(skip_serializing_if = "Option::is_none")]
59 year: Option<&'a [u32]>,
60
61 /// Filtering materials by translation ID
62 #[serde(skip_serializing_if = "Option::is_none")]
63 translation_id: Option<&'a [u32]>,
64 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
65 #[serde(skip_serializing_if = "Option::is_none")]
66 translation_type: Option<&'a [TranslationType]>,
67
68 /// Filtering materials based on the presence of a specific field. Materials that have at least one of the listed fields are shown. In order to show only materials that have all the listed fields
69 #[serde(skip_serializing_if = "Option::is_none")]
70 has_field: Option<&'a [MaterialDataField]>,
71 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
72 #[serde(skip_serializing_if = "Option::is_none")]
73 has_field_and: Option<&'a [MaterialDataField]>,
74
75 /// Filtering materials by country. You can specify a single value or multiple values, separated by commas (then materials with at least one of the listed countries will be displayed). The parameter is case sensitive
76 #[serde(skip_serializing_if = "Option::is_none")]
77 countries: Option<&'a [&'a str]>,
78
79 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
80 #[serde(skip_serializing_if = "Option::is_none")]
81 genres: Option<&'a [&'a str]>,
82 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
83 #[serde(skip_serializing_if = "Option::is_none")]
84 anime_genres: Option<&'a [&'a str]>,
85 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
86 #[serde(skip_serializing_if = "Option::is_none")]
87 drama_genres: Option<&'a [&'a str]>,
88 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
89 #[serde(skip_serializing_if = "Option::is_none")]
90 all_genres: Option<&'a [&'a str]>,
91
92 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
93 #[serde(skip_serializing_if = "Option::is_none")]
94 duration: Option<&'a [&'a str]>,
95
96 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
97 #[serde(skip_serializing_if = "Option::is_none")]
98 kinopoisk_rating: Option<&'a [&'a str]>,
99 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
100 #[serde(skip_serializing_if = "Option::is_none")]
101 imdb_rating: Option<&'a [&'a str]>,
102 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
103 #[serde(skip_serializing_if = "Option::is_none")]
104 shikimori_rating: Option<&'a [&'a str]>,
105 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
106 #[serde(skip_serializing_if = "Option::is_none")]
107 mydramalist_rating: Option<&'a [&'a str]>,
108
109 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
110 #[serde(skip_serializing_if = "Option::is_none")]
111 actors: Option<&'a [&'a str]>,
112 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
113 #[serde(skip_serializing_if = "Option::is_none")]
114 directors: Option<&'a [&'a str]>,
115 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
116 #[serde(skip_serializing_if = "Option::is_none")]
117 producers: Option<&'a [&'a str]>,
118 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
119 #[serde(skip_serializing_if = "Option::is_none")]
120 writers: Option<&'a [&'a str]>,
121 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
122 #[serde(skip_serializing_if = "Option::is_none")]
123 composers: Option<&'a [&'a str]>,
124 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
125 #[serde(skip_serializing_if = "Option::is_none")]
126 editors: Option<&'a [&'a str]>,
127 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
128 #[serde(skip_serializing_if = "Option::is_none")]
129 designers: Option<&'a [&'a str]>,
130 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
131 #[serde(skip_serializing_if = "Option::is_none")]
132 operators: Option<&'a [&'a str]>,
133
134 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
135 #[serde(skip_serializing_if = "Option::is_none")]
136 rating_mpaa: Option<&'a [MppaRating]>,
137
138 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
139 #[serde(skip_serializing_if = "Option::is_none")]
140 minimal_age: Option<&'a [&'a str]>,
141
142 /// Filtering materials by anime type. You can specify one value or several values separated by commas (then materials with at least one of these types will be displayed)
143 #[serde(skip_serializing_if = "Option::is_none")]
144 anime_kind: Option<&'a [AnimeKind]>,
145
146 /// Filters materials by MyDramaList tags. You can specify one value or several values separated by commas (then materials with at least one of these types will be displayed)
147 #[serde(skip_serializing_if = "Option::is_none")]
148 mydramalist_tags: Option<&'a [&'a str]>,
149
150 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
151 #[serde(skip_serializing_if = "Option::is_none")]
152 anime_status: Option<&'a [AnimeStatus]>,
153 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
154 #[serde(skip_serializing_if = "Option::is_none")]
155 drama_status: Option<&'a [DramaStatus]>,
156 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
157 #[serde(skip_serializing_if = "Option::is_none")]
158 all_status: Option<&'a [AllStatus]>,
159
160 /// Filtering materials by anime studio. You can specify either one value or several values separated by commas (then materials with at least one of the listed studios will be displayed)
161 #[serde(skip_serializing_if = "Option::is_none")]
162 anime_studios: Option<&'a [&'a str]>,
163 /// Filtering materials by license owner. You can specify a single value or several values separated by commas (then materials that have at least one of the listed owners will be displayed)
164 #[serde(skip_serializing_if = "Option::is_none")]
165 anime_licensed_by: Option<&'a [&'a str]>,
166}
167
168impl<'a> CountryQuery<'a> {
169 pub fn new() -> CountryQuery<'a> {
170 CountryQuery {
171 sort: None,
172 types: None,
173 year: None,
174 translation_id: None,
175 translation_type: None,
176 has_field: None,
177 has_field_and: None,
178 countries: None,
179 genres: None,
180 anime_genres: None,
181 drama_genres: None,
182 all_genres: None,
183 duration: None,
184 kinopoisk_rating: None,
185 imdb_rating: None,
186 shikimori_rating: None,
187 mydramalist_rating: None,
188 actors: None,
189 directors: None,
190 producers: None,
191 writers: None,
192 composers: None,
193 editors: None,
194 designers: None,
195 operators: None,
196 rating_mpaa: None,
197 minimal_age: None,
198 anime_kind: None,
199 mydramalist_tags: None,
200 anime_status: None,
201 drama_status: None,
202 all_status: None,
203 anime_studios: None,
204 anime_licensed_by: None,
205 }
206 }
207
208 /// Maximum number of outputs
209 pub fn with_types<'b>(&'b mut self, types: &'a [ReleaseType]) -> &'b mut CountryQuery<'a> {
210 self.types = Some(types);
211 self
212 }
213
214 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
215
216 pub fn with_year<'b>(&'b mut self, year: &'a [u32]) -> &'b mut CountryQuery<'a> {
217 self.year = Some(year);
218 self
219 }
220
221 /// Filtering materials by translation ID
222 pub fn with_translation_id<'b>(
223 &'b mut self,
224 translation_id: &'a [u32],
225 ) -> &'b mut CountryQuery<'a> {
226 self.translation_id = Some(translation_id);
227 self
228 }
229 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
230 pub fn with_translation_type<'b>(
231 &'b mut self,
232 translation_type: &'a [TranslationType],
233 ) -> &'b mut CountryQuery<'a> {
234 self.translation_type = Some(translation_type);
235 self
236 }
237
238 /// Filtering materials based on the presence of a specific field. Materials that have at least one of the listed fields are shown. In order to show only materials that have all the listed fields
239 pub fn with_has_field<'b>(
240 &'b mut self,
241 has_field: &'a [MaterialDataField],
242 ) -> &'b mut CountryQuery<'a> {
243 self.has_field = Some(has_field);
244 self
245 }
246 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
247 pub fn with_has_field_and<'b>(
248 &'b mut self,
249 has_field: &'a [MaterialDataField],
250 ) -> &'b mut CountryQuery<'a> {
251 self.has_field_and = Some(has_field);
252 self
253 }
254
255 /// Filtering materials by country. You can specify a single value or multiple values, separated by commas (then materials with at least one of the listed countries will be displayed). The parameter is case sensitive
256 pub fn with_countries<'b>(&'b mut self, countries: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
257 self.countries = Some(countries);
258 self
259 }
260
261 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
262 pub fn with_genres<'b>(&'b mut self, genres: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
263 self.genres = Some(genres);
264 self
265 }
266 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
267 pub fn with_anime_genres<'b>(
268 &'b mut self,
269 anime_genres: &'a [&'a str],
270 ) -> &'b mut CountryQuery<'a> {
271 self.anime_genres = Some(anime_genres);
272 self
273 }
274 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
275 pub fn with_drama_genres<'b>(
276 &'b mut self,
277 drama_genres: &'a [&'a str],
278 ) -> &'b mut CountryQuery<'a> {
279 self.drama_genres = Some(drama_genres);
280 self
281 }
282 /// Filtering by genre. You can specify either one value or several values separated by commas (then materials that have at least one of the specified genres will be displayed). You can search by Kinopoisk, Shikimori, MyDramaList or by all genres at once. The parameter is not case sensitive
283 pub fn with_all_genres<'b>(
284 &'b mut self,
285 all_genres: &'a [&'a str],
286 ) -> &'b mut CountryQuery<'a> {
287 self.all_genres = Some(all_genres);
288 self
289 }
290
291 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
292 pub fn with_duration<'b>(&'b mut self, duration: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
293 self.duration = Some(duration);
294 self
295 }
296
297 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
298 pub fn with_kinopoisk_rating<'b>(
299 &'b mut self,
300 kinopoisk_rating: &'a [&'a str],
301 ) -> &'b mut CountryQuery<'a> {
302 self.kinopoisk_rating = Some(kinopoisk_rating);
303 self
304 }
305 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
306 pub fn with_imdb_rating<'b>(
307 &'b mut self,
308 imdb_rating: &'a [&'a str],
309 ) -> &'b mut CountryQuery<'a> {
310 self.imdb_rating = Some(imdb_rating);
311 self
312 }
313 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
314 pub fn with_shikimori_rating<'b>(
315 &'b mut self,
316 shikimori_rating: &'a [&'a str],
317 ) -> &'b mut CountryQuery<'a> {
318 self.shikimori_rating = Some(shikimori_rating);
319 self
320 }
321 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
322 pub fn with_mydramalist_rating<'b>(
323 &'b mut self,
324 mydramalist_rating: &'a [&'a str],
325 ) -> &'b mut CountryQuery<'a> {
326 self.mydramalist_rating = Some(mydramalist_rating);
327 self
328 }
329
330 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
331 pub fn with_actors<'b>(&'b mut self, actors: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
332 self.actors = Some(actors);
333 self
334 }
335 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
336 pub fn with_directors<'b>(&'b mut self, directors: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
337 self.directors = Some(directors);
338 self
339 }
340 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
341 pub fn with_producers<'b>(&'b mut self, producers: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
342 self.producers = Some(producers);
343 self
344 }
345 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
346 pub fn with_writers<'b>(&'b mut self, writers: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
347 self.writers = Some(writers);
348 self
349 }
350 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
351 pub fn with_composers<'b>(&'b mut self, composers: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
352 self.composers = Some(composers);
353 self
354 }
355 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
356 pub fn with_editors<'b>(&'b mut self, editors: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
357 self.editors = Some(editors);
358 self
359 }
360 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
361 pub fn with_designers<'b>(&'b mut self, designers: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
362 self.designers = Some(designers);
363 self
364 }
365 /// Filtering materials by personas. You can specify a single value or multiple values, separated by commas (then materials that have at least one of the specified personas will be displayed). This parameter is case-independent. You can specify filters for several professions at once
366 pub fn with_operators<'b>(&'b mut self, operators: &'a [&'a str]) -> &'b mut CountryQuery<'a> {
367 self.operators = Some(operators);
368 self
369 }
370
371 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
372 pub fn with_rating_mpaa<'b>(
373 &'b mut self,
374 rating_mpaa: &'a [MppaRating],
375 ) -> &'b mut CountryQuery<'a> {
376 self.rating_mpaa = Some(rating_mpaa);
377 self
378 }
379
380 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
381 pub fn with_minimal_age<'b>(
382 &'b mut self,
383 minimal_age: &'a [&'a str],
384 ) -> &'b mut CountryQuery<'a> {
385 self.minimal_age = Some(minimal_age);
386 self
387 }
388
389 /// Filtering materials by anime type. You can specify one value or several values separated by commas (then materials with at least one of these types will be displayed)
390 pub fn with_anime_kind<'b>(
391 &'b mut self,
392 anime_kind: &'a [AnimeKind],
393 ) -> &'b mut CountryQuery<'a> {
394 self.anime_kind = Some(anime_kind);
395 self
396 }
397
398 /// Filters materials by MyDramaList tags. You can specify one value or several values separated by commas (then materials with at least one of these types will be displayed)
399 pub fn with_mydramalist_tags<'b>(
400 &'b mut self,
401 mydramalist_tags: &'a [&'a str],
402 ) -> &'b mut CountryQuery<'a> {
403 self.mydramalist_tags = Some(mydramalist_tags);
404 self
405 }
406
407 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
408 pub fn with_anime_status<'b>(
409 &'b mut self,
410 anime_status: &'a [AnimeStatus],
411 ) -> &'b mut CountryQuery<'a> {
412 self.anime_status = Some(anime_status);
413 self
414 }
415 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
416 pub fn with_drama_status<'b>(
417 &'b mut self,
418 drama_status: &'a [DramaStatus],
419 ) -> &'b mut CountryQuery<'a> {
420 self.drama_status = Some(drama_status);
421 self
422 }
423 /// Filter materials by Shikimori status, MyDramaList, or by all statuses. You can specify a single value or several values separated by commas (then materials that have at least one of the listed statuses will be displayed)
424 pub fn with_all_status<'b>(
425 &'b mut self,
426 all_status: &'a [AllStatus],
427 ) -> &'b mut CountryQuery<'a> {
428 self.all_status = Some(all_status);
429 self
430 }
431
432 /// Filtering materials by anime studio. You can specify either one value or several values separated by commas (then materials with at least one of the listed studios will be displayed)
433 pub fn with_anime_studios<'b>(
434 &'b mut self,
435 anime_studios: &'a [&'a str],
436 ) -> &'b mut CountryQuery<'a> {
437 self.anime_studios = Some(anime_studios);
438 self
439 }
440 /// Filtering materials by license owner. You can specify a single value or several values separated by commas (then materials that have at least one of the listed owners will be displayed)
441 pub fn with_anime_licensed_by<'b>(
442 &'b mut self,
443 anime_licensed_by: &'a [&'a str],
444 ) -> &'b mut CountryQuery<'a> {
445 self.anime_licensed_by = Some(anime_licensed_by);
446 self
447 }
448
449 /// Execute the query and fetch the results.
450 pub async fn execute<'b>(&'a self, client: &'b Client) -> Result<CountryResponse, Error> {
451 let payload = serialize_into_query_parts(self)?;
452
453 let response = client
454 .init_post_request("/countries")
455 .query(&payload)
456 .send()
457 .await
458 .map_err(Error::HttpError)?;
459
460 let result = response
461 .json::<CountryResponseUnion>()
462 .await
463 .map_err(Error::HttpError)?;
464
465 match result {
466 CountryResponseUnion::Result(result) => Ok(result),
467 CountryResponseUnion::Error { error } => Err(Error::KodikError(error)),
468 }
469 }
470}
471
472impl<'a> Default for CountryQuery<'a> {
473 fn default() -> Self {
474 Self::new()
475 }
476}