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