kodik_api/qualities.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 QualityResult {
15 // Name of quality
16 pub title: String,
17 pub count: i32,
18}
19
20/// A struct containing qualities results
21#[derive(Deserialize, Debug, Clone)]
22pub struct QualityResponse {
23 pub time: String,
24 pub total: i32,
25 pub results: Vec<QualityResult>,
26}
27
28#[derive(Deserialize, Debug, Clone)]
29#[serde(untagged)]
30enum QualityResponseUnion {
31 Result(QualityResponse),
32 Error { error: String },
33}
34
35#[derive(Serialize, Deserialize, Debug, Clone)]
36pub enum QualitySort {
37 #[serde(rename = "title")]
38 Title,
39 #[serde(rename = "count")]
40 Count,
41}
42
43#[derive(Debug, Serialize, Clone)]
44pub struct QualityQuery<'a> {
45 /// What field to sort materials by
46 #[serde(skip_serializing_if = "Option::is_none")]
47 sort: Option<QualitySort>,
48
49 /// Filtering materials by their type. For your convenience, a large number of types of films and TV series are available. Required types are specified separated by commas
50 #[serde(skip_serializing_if = "Option::is_none")]
51 types: Option<&'a [ReleaseType]>,
52
53 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
54 #[serde(skip_serializing_if = "Option::is_none")]
55 year: Option<&'a [u32]>,
56
57 /// Filtering materials by translation ID
58 #[serde(skip_serializing_if = "Option::is_none")]
59 translation_id: Option<&'a [u32]>,
60 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
61 #[serde(skip_serializing_if = "Option::is_none")]
62 translation_type: Option<&'a [TranslationType]>,
63
64 /// 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
65 #[serde(skip_serializing_if = "Option::is_none")]
66 has_field: Option<&'a [MaterialDataField]>,
67 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
68 #[serde(skip_serializing_if = "Option::is_none")]
69 has_field_and: Option<&'a [MaterialDataField]>,
70
71 /// Filters materials by the lgbt parameter. If you specify false, only materials that do not contain LGBT scenes will be output. If you don't specify this parameter, all materials will be displayed
72 #[serde(skip_serializing_if = "Option::is_none")]
73 lgbt: Option<bool>,
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> QualityQuery<'a> {
169 pub fn new() -> QualityQuery<'a> {
170 QualityQuery {
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 lgbt: None,
179 countries: None,
180 genres: None,
181 anime_genres: None,
182 drama_genres: None,
183 all_genres: None,
184 duration: None,
185 kinopoisk_rating: None,
186 imdb_rating: None,
187 shikimori_rating: None,
188 mydramalist_rating: None,
189 actors: None,
190 directors: None,
191 producers: None,
192 writers: None,
193 composers: None,
194 editors: None,
195 designers: None,
196 operators: None,
197 minimal_age: None,
198 rating_mpaa: None,
199 anime_kind: None,
200 mydramalist_tags: None,
201 anime_status: None,
202 drama_status: None,
203 all_status: None,
204 anime_studios: None,
205 anime_licensed_by: None,
206 }
207 }
208
209 /// What field to sort materials by
210 pub fn with_sort<'b>(&'b mut self, sort: QualitySort) -> &'b mut QualityQuery<'a> {
211 self.sort = Some(sort);
212 self
213 }
214
215 /// Filtering materials by their type. For your convenience, a large number of types of films and TV series are available. Required types are specified separated by commas
216 pub fn with_types<'b>(&'b mut self, types: &'a [ReleaseType]) -> &'b mut QualityQuery<'a> {
217 self.types = Some(types);
218 self
219 }
220
221 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
222 pub fn with_year<'b>(&'b mut self, year: &'a [u32]) -> &'b mut QualityQuery<'a> {
223 self.year = Some(year);
224 self
225 }
226
227 /// Filtering materials by translation ID
228 pub fn with_translation_id<'b>(
229 &'b mut self,
230 translation_id: &'a [u32],
231 ) -> &'b mut QualityQuery<'a> {
232 self.translation_id = Some(translation_id);
233 self
234 }
235
236 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
237 pub fn with_translation_type<'b>(
238 &'b mut self,
239 translation_type: &'a [TranslationType],
240 ) -> &'b mut QualityQuery<'a> {
241 self.translation_type = Some(translation_type);
242 self
243 }
244
245 /// 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
246 pub fn with_has_field<'b>(
247 &'b mut self,
248 has_field: &'a [MaterialDataField],
249 ) -> &'b mut QualityQuery<'a> {
250 self.has_field = Some(has_field);
251 self
252 }
253 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
254 pub fn with_has_field_and<'b>(
255 &'b mut self,
256 has_field: &'a [MaterialDataField],
257 ) -> &'b mut QualityQuery<'a> {
258 self.has_field_and = Some(has_field);
259 self
260 }
261
262 /// Filters materials by the lgbt parameter. If you specify false, only materials that do not contain LGBT scenes will be output. If you don't specify this parameter, all materials will be displayed
263 pub fn with_lgbt<'b>(&'b mut self, lgbt: bool) -> &'b mut QualityQuery<'a> {
264 self.lgbt = Some(lgbt);
265 self
266 }
267
268 /// 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
269 pub fn with_countries<'b>(&'b mut self, countries: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
270 self.countries = Some(countries);
271 self
272 }
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_genres<'b>(&'b mut self, genres: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
276 self.genres = Some(genres);
277 self
278 }
279 /// 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
280 pub fn with_anime_genres<'b>(
281 &'b mut self,
282 anime_genres: &'a [&'a str],
283 ) -> &'b mut QualityQuery<'a> {
284 self.anime_genres = Some(anime_genres);
285 self
286 }
287 /// 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
288 pub fn with_drama_genres<'b>(
289 &'b mut self,
290 drama_genres: &'a [&'a str],
291 ) -> &'b mut QualityQuery<'a> {
292 self.drama_genres = Some(drama_genres);
293 self
294 }
295 /// 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
296 pub fn with_all_genres<'b>(
297 &'b mut self,
298 all_genres: &'a [&'a str],
299 ) -> &'b mut QualityQuery<'a> {
300 self.all_genres = Some(all_genres);
301 self
302 }
303
304 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
305 pub fn with_duration<'b>(&'b mut self, duration: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
306 self.duration = Some(duration);
307 self
308 }
309
310 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
311 pub fn with_kinopoisk_rating<'b>(
312 &'b mut self,
313 kinopoisk_rating: &'a [&'a str],
314 ) -> &'b mut QualityQuery<'a> {
315 self.kinopoisk_rating = Some(kinopoisk_rating);
316 self
317 }
318 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
319 pub fn with_imdb_rating<'b>(
320 &'b mut self,
321 imdb_rating: &'a [&'a str],
322 ) -> &'b mut QualityQuery<'a> {
323 self.imdb_rating = Some(imdb_rating);
324 self
325 }
326 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
327 pub fn with_shikimori_rating<'b>(
328 &'b mut self,
329 shikimori_rating: &'a [&'a str],
330 ) -> &'b mut QualityQuery<'a> {
331 self.shikimori_rating = Some(shikimori_rating);
332 self
333 }
334 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
335 pub fn with_mydramalist_rating<'b>(
336 &'b mut self,
337 mydramalist_rating: &'a [&'a str],
338 ) -> &'b mut QualityQuery<'a> {
339 self.mydramalist_rating = Some(mydramalist_rating);
340 self
341 }
342
343 /// 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
344 pub fn with_actors<'b>(&'b mut self, actors: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
345 self.actors = Some(actors);
346 self
347 }
348 /// 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
349 pub fn with_directors<'b>(&'b mut self, directors: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
350 self.directors = Some(directors);
351 self
352 }
353 /// 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
354 pub fn with_producers<'b>(&'b mut self, producers: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
355 self.producers = Some(producers);
356 self
357 }
358 /// 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
359 pub fn with_writers<'b>(&'b mut self, writers: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
360 self.writers = Some(writers);
361 self
362 }
363 /// 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
364 pub fn with_composers<'b>(&'b mut self, composers: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
365 self.composers = Some(composers);
366 self
367 }
368 /// 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
369 pub fn with_editors<'b>(&'b mut self, editors: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
370 self.editors = Some(editors);
371 self
372 }
373 /// 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
374 pub fn with_designers<'b>(&'b mut self, designers: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
375 self.designers = Some(designers);
376 self
377 }
378 /// 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
379 pub fn with_operators<'b>(&'b mut self, operators: &'a [&'a str]) -> &'b mut QualityQuery<'a> {
380 self.operators = Some(operators);
381 self
382 }
383
384 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
385 pub fn with_rating_mpaa<'b>(
386 &'b mut self,
387 rating_mpaa: &'a [MppaRating],
388 ) -> &'b mut QualityQuery<'a> {
389 self.rating_mpaa = Some(rating_mpaa);
390 self
391 }
392
393 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
394 pub fn with_minimal_age<'b>(
395 &'b mut self,
396 minimal_age: &'a [&'a str],
397 ) -> &'b mut QualityQuery<'a> {
398 self.minimal_age = Some(minimal_age);
399 self
400 }
401
402 /// 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)
403 pub fn with_anime_kind<'b>(
404 &'b mut self,
405 anime_kind: &'a [AnimeKind],
406 ) -> &'b mut QualityQuery<'a> {
407 self.anime_kind = Some(anime_kind);
408 self
409 }
410
411 /// 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)
412 pub fn with_mydramalist_tags<'b>(
413 &'b mut self,
414 mydramalist_tags: &'a [&'a str],
415 ) -> &'b mut QualityQuery<'a> {
416 self.mydramalist_tags = Some(mydramalist_tags);
417 self
418 }
419
420 /// 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)
421 pub fn with_anime_status<'b>(
422 &'b mut self,
423 anime_status: &'a [AnimeStatus],
424 ) -> &'b mut QualityQuery<'a> {
425 self.anime_status = Some(anime_status);
426 self
427 }
428 /// 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)
429 pub fn with_drama_status<'b>(
430 &'b mut self,
431 drama_status: &'a [DramaStatus],
432 ) -> &'b mut QualityQuery<'a> {
433 self.drama_status = Some(drama_status);
434 self
435 }
436 /// 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)
437 pub fn with_all_status<'b>(
438 &'b mut self,
439 all_status: &'a [AllStatus],
440 ) -> &'b mut QualityQuery<'a> {
441 self.all_status = Some(all_status);
442 self
443 }
444
445 /// 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)
446 pub fn with_anime_studios<'b>(
447 &'b mut self,
448 anime_studios: &'a [&'a str],
449 ) -> &'b mut QualityQuery<'a> {
450 self.anime_studios = Some(anime_studios);
451 self
452 }
453 /// 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)
454 pub fn with_anime_licensed_by<'b>(
455 &'b mut self,
456 anime_licensed_by: &'a [&'a str],
457 ) -> &'b mut QualityQuery<'a> {
458 self.anime_licensed_by = Some(anime_licensed_by);
459 self
460 }
461
462 /// Execute the query and fetch the results.
463 pub async fn execute<'b>(&'a self, client: &'b Client) -> Result<QualityResponse, Error> {
464 let payload = serialize_into_query_parts(self)?;
465
466 let response = client
467 .init_post_request("/qualities/v2")
468 .query(&payload)
469 .send()
470 .await
471 .map_err(Error::HttpError)?;
472
473 let result = response
474 .json::<QualityResponseUnion>()
475 .await
476 .map_err(Error::HttpError)?;
477
478 match result {
479 QualityResponseUnion::Result(result) => Ok(result),
480 QualityResponseUnion::Error { error } => Err(Error::KodikError(error)),
481 }
482 }
483}
484
485impl<'a> Default for QualityQuery<'a> {
486 fn default() -> Self {
487 Self::new()
488 }
489}