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