kodik_api/years.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 Client,
5 error::Error,
6 types::{
7 AllStatus, AnimeKind, AnimeStatus, DramaStatus, MaterialDataField, MppaRating, ReleaseType,
8 TranslationType,
9 },
10 util::serialize_into_query_parts,
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 pub fn with_year<'b>(&'b mut self, year: &'a [u32]) -> &'b mut YearQuery<'a> {
215 self.year = Some(year);
216 self
217 }
218
219 /// Filtering materials by translation ID
220 pub fn with_translation_id<'b>(
221 &'b mut self,
222 translation_id: &'a [u32],
223 ) -> &'b mut YearQuery<'a> {
224 self.translation_id = Some(translation_id);
225 self
226 }
227 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
228 pub fn with_translation_type<'b>(
229 &'b mut self,
230 translation_type: &'a [TranslationType],
231 ) -> &'b mut YearQuery<'a> {
232 self.translation_type = Some(translation_type);
233 self
234 }
235
236 /// 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
237 pub fn with_has_field<'b>(
238 &'b mut self,
239 has_field: &'a [MaterialDataField],
240 ) -> &'b mut YearQuery<'a> {
241 self.has_field = Some(has_field);
242 self
243 }
244 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
245 pub fn with_has_field_and<'b>(
246 &'b mut self,
247 has_field: &'a [MaterialDataField],
248 ) -> &'b mut YearQuery<'a> {
249 self.has_field_and = Some(has_field);
250 self
251 }
252
253 /// 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
254 pub fn with_countries<'b>(&'b mut self, countries: &'a [&'a str]) -> &'b mut YearQuery<'a> {
255 self.countries = Some(countries);
256 self
257 }
258
259 /// 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
260 pub fn with_genres<'b>(&'b mut self, genres: &'a [&'a str]) -> &'b mut YearQuery<'a> {
261 self.genres = Some(genres);
262 self
263 }
264 /// 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
265 pub fn with_anime_genres<'b>(
266 &'b mut self,
267 anime_genres: &'a [&'a str],
268 ) -> &'b mut YearQuery<'a> {
269 self.anime_genres = Some(anime_genres);
270 self
271 }
272 /// 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
273 pub fn with_drama_genres<'b>(
274 &'b mut self,
275 drama_genres: &'a [&'a str],
276 ) -> &'b mut YearQuery<'a> {
277 self.drama_genres = Some(drama_genres);
278 self
279 }
280 /// 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
281 pub fn with_all_genres<'b>(&'b mut self, all_genres: &'a [&'a str]) -> &'b mut YearQuery<'a> {
282 self.all_genres = Some(all_genres);
283 self
284 }
285
286 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
287 pub fn with_duration<'b>(&'b mut self, duration: &'a [&'a str]) -> &'b mut YearQuery<'a> {
288 self.duration = Some(duration);
289 self
290 }
291
292 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
293 pub fn with_kinopoisk_rating<'b>(
294 &'b mut self,
295 kinopoisk_rating: &'a [&'a str],
296 ) -> &'b mut YearQuery<'a> {
297 self.kinopoisk_rating = Some(kinopoisk_rating);
298 self
299 }
300 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
301 pub fn with_imdb_rating<'b>(&'b mut self, imdb_rating: &'a [&'a str]) -> &'b mut YearQuery<'a> {
302 self.imdb_rating = Some(imdb_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_shikimori_rating<'b>(
307 &'b mut self,
308 shikimori_rating: &'a [&'a str],
309 ) -> &'b mut YearQuery<'a> {
310 self.shikimori_rating = Some(shikimori_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_mydramalist_rating<'b>(
315 &'b mut self,
316 mydramalist_rating: &'a [&'a str],
317 ) -> &'b mut YearQuery<'a> {
318 self.mydramalist_rating = Some(mydramalist_rating);
319 self
320 }
321
322 /// 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
323 pub fn with_actors<'b>(&'b mut self, actors: &'a [&'a str]) -> &'b mut YearQuery<'a> {
324 self.actors = Some(actors);
325 self
326 }
327 /// 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
328 pub fn with_directors<'b>(&'b mut self, directors: &'a [&'a str]) -> &'b mut YearQuery<'a> {
329 self.directors = Some(directors);
330 self
331 }
332 /// 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
333 pub fn with_producers<'b>(&'b mut self, producers: &'a [&'a str]) -> &'b mut YearQuery<'a> {
334 self.producers = Some(producers);
335 self
336 }
337 /// 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
338 pub fn with_writers<'b>(&'b mut self, writers: &'a [&'a str]) -> &'b mut YearQuery<'a> {
339 self.writers = Some(writers);
340 self
341 }
342 /// 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
343 pub fn with_composers<'b>(&'b mut self, composers: &'a [&'a str]) -> &'b mut YearQuery<'a> {
344 self.composers = Some(composers);
345 self
346 }
347 /// 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
348 pub fn with_editors<'b>(&'b mut self, editors: &'a [&'a str]) -> &'b mut YearQuery<'a> {
349 self.editors = Some(editors);
350 self
351 }
352 /// 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
353 pub fn with_designers<'b>(&'b mut self, designers: &'a [&'a str]) -> &'b mut YearQuery<'a> {
354 self.designers = Some(designers);
355 self
356 }
357 /// 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
358 pub fn with_operators<'b>(&'b mut self, operators: &'a [&'a str]) -> &'b mut YearQuery<'a> {
359 self.operators = Some(operators);
360 self
361 }
362
363 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
364 pub fn with_rating_mpaa<'b>(
365 &'b mut self,
366 rating_mpaa: &'a [MppaRating],
367 ) -> &'b mut YearQuery<'a> {
368 self.rating_mpaa = Some(rating_mpaa);
369 self
370 }
371
372 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
373 pub fn with_minimal_age<'b>(&'b mut self, minimal_age: &'a [&'a str]) -> &'b mut YearQuery<'a> {
374 self.minimal_age = Some(minimal_age);
375 self
376 }
377
378 /// 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)
379 pub fn with_anime_kind<'b>(&'b mut self, anime_kind: &'a [AnimeKind]) -> &'b mut YearQuery<'a> {
380 self.anime_kind = Some(anime_kind);
381 self
382 }
383
384 /// 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)
385 pub fn with_mydramalist_tags<'b>(
386 &'b mut self,
387 mydramalist_tags: &'a [&'a str],
388 ) -> &'b mut YearQuery<'a> {
389 self.mydramalist_tags = Some(mydramalist_tags);
390 self
391 }
392
393 /// 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)
394 pub fn with_anime_status<'b>(
395 &'b mut self,
396 anime_status: &'a [AnimeStatus],
397 ) -> &'b mut YearQuery<'a> {
398 self.anime_status = Some(anime_status);
399 self
400 }
401 /// 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)
402 pub fn with_drama_status<'b>(
403 &'b mut self,
404 drama_status: &'a [DramaStatus],
405 ) -> &'b mut YearQuery<'a> {
406 self.drama_status = Some(drama_status);
407 self
408 }
409 /// 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)
410 pub fn with_all_status<'b>(&'b mut self, all_status: &'a [AllStatus]) -> &'b mut YearQuery<'a> {
411 self.all_status = Some(all_status);
412 self
413 }
414
415 /// 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)
416 pub fn with_anime_studios<'b>(
417 &'b mut self,
418 anime_studios: &'a [&'a str],
419 ) -> &'b mut YearQuery<'a> {
420 self.anime_studios = Some(anime_studios);
421 self
422 }
423 /// 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)
424 pub fn with_anime_licensed_by<'b>(
425 &'b mut self,
426 anime_licensed_by: &'a [&'a str],
427 ) -> &'b mut YearQuery<'a> {
428 self.anime_licensed_by = Some(anime_licensed_by);
429 self
430 }
431
432 /// Execute the query and fetch the results.
433 pub async fn execute<'b>(&'a self, client: &'b Client) -> Result<YearResponse, Error> {
434 let payload = serialize_into_query_parts(self)?;
435
436 let response = client
437 .init_post_request("/years")
438 .query(&payload)
439 .send()
440 .await
441 .map_err(Error::HttpError)?;
442
443 let result = response
444 .json::<YearResponseUnion>()
445 .await
446 .map_err(Error::HttpError)?;
447
448 match result {
449 YearResponseUnion::Result(result) => Ok(result),
450 YearResponseUnion::Error { error } => Err(Error::KodikError(error)),
451 }
452 }
453}
454
455impl<'a> Default for YearQuery<'a> {
456 fn default() -> Self {
457 Self::new()
458 }
459}