kodik_api/search.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 error::Error,
5 types::{
6 AllStatus, AnimeKind, AnimeStatus, DramaStatus, MaterialDataField, MppaRating, Release,
7 ReleaseType, TranslationType,
8 },
9 util::serialize_into_query_parts,
10 Client,
11};
12
13/// A struct containing search results and other information about the search
14#[derive(Deserialize, Debug, Clone)]
15pub struct SearchResponse {
16 pub time: String,
17 pub total: i32,
18 pub prev_page: Option<String>,
19 pub next_page: Option<String>,
20 pub results: Vec<Release>,
21}
22
23#[derive(Deserialize, Debug, Clone)]
24#[serde(untagged)]
25enum SearchResponseUnion {
26 Result(SearchResponse),
27 Error { error: String },
28}
29
30#[derive(Debug, Serialize, Clone)]
31pub struct SearchQuery<'a> {
32 /// The name of the movie. It is not necessary to specify it explicitly, you can use a variant written by the user or a variant containing extra words. If you specify one of these parameters, the search will be performed on several fields at once: `title`, `title_orig`, `other_title`
33 #[serde(skip_serializing_if = "Option::is_none")]
34 title: Option<&'a str>,
35 /// Original title. When this option is used, only the title_orig will be searched. It is not necessary to specify it explicitly, you can use a variant written by the user or a variant containing extra words
36 #[serde(skip_serializing_if = "Option::is_none")]
37 title_orig: Option<&'a str>,
38 /// If title or title_orig parameter was specified, this parameter defines the severity of checking if the title of the material corresponds to the search query. If true, the search results will show only those materials in which the word order is exactly the same as in the search query (but extra words in the search query are still allowed)
39 #[serde(skip_serializing_if = "Option::is_none")]
40 strict: Option<bool>,
41 /// If title or title_orig parameter was specified, this parameter defines the severity of checking if the title of the material corresponds to the search query. If true, the search results will only show content where the title completely matches the search query (no extra words, word order and presence of characters are also completely identical). The only thing the title may differ from the query is the case. When used in conjunction with the title, full consistency with at least one of the titles of the material is checked
42 #[serde(skip_serializing_if = "Option::is_none")]
43 full_match: Option<bool>,
44
45 /// Search by Kodik ID
46 #[serde(skip_serializing_if = "Option::is_none")]
47 id: Option<&'a str>,
48 /// Search for any link to the player
49 #[serde(skip_serializing_if = "Option::is_none")]
50 player_link: Option<&'a str>,
51
52 /// Search by kinopoisk ID
53 #[serde(skip_serializing_if = "Option::is_none")]
54 kinopoisk_id: Option<&'a str>,
55 /// Search by IMDb ID
56 #[serde(skip_serializing_if = "Option::is_none")]
57 imdb_id: Option<&'a str>,
58 /// Search by MyDramaList ID
59 #[serde(skip_serializing_if = "Option::is_none")]
60 mdl_id: Option<&'a str>,
61
62 /// Search for World Art IDs in the anime section (World Art has different content sections, each with their own independent IDs)
63 #[serde(skip_serializing_if = "Option::is_none")]
64 worldart_animation_id: Option<&'a str>,
65 /// Search for World Art IDs in the Movies section
66 #[serde(skip_serializing_if = "Option::is_none")]
67 worldart_cinema_id: Option<&'a str>,
68 /// Search the full World Art link
69 #[serde(skip_serializing_if = "Option::is_none")]
70 worldart_link: Option<&'a str>,
71 /// Search by Shikimori ID
72 #[serde(skip_serializing_if = "Option::is_none")]
73 shikimori_id: Option<&'a str>,
74
75 /// Maximum number of outputs
76 #[serde(skip_serializing_if = "Option::is_none")]
77 limit: Option<u32>,
78
79 /// 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
80 #[serde(skip_serializing_if = "Option::is_none")]
81 types: Option<&'a [ReleaseType]>,
82
83 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
84 #[serde(skip_serializing_if = "Option::is_none")]
85 year: Option<&'a [u32]>,
86
87 /// Filtering materials by translation ID
88 #[serde(skip_serializing_if = "Option::is_none")]
89 translation_id: Option<&'a [u32]>,
90 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
91 #[serde(skip_serializing_if = "Option::is_none")]
92 translation_type: Option<&'a [TranslationType]>,
93 /// Increases the priority of certain voices. The IDs are listed in commas. The "leftmost" ID, the higher its priority. IDs of all voices can be received through API resource /translations or on the page of list of voices. Standard priority of dubbed and prof. Multivoiced". To deactivate standard priority you need to pass value 0. You can also specify the translation type (subtitles/voice) instead of the ID
94 #[serde(skip_serializing_if = "Option::is_none")]
95 // TODO: Add wrapper
96 prioritize_translations: Option<&'a [&'a str]>,
97 /// Decreases the priority of certain voices. The IDs are listed in commas. The "leftmost" ID, the lower its priority. IDs of all voices can be received through API resource /translations or on page of voices list. Standard priority of soundtracks "Ukrainian", "English" and all subtitles are lowered. To deactivate standard priority you need to pass value 0. You can also specify the translation type (subtitles/voice) instead of the ID
98 #[serde(skip_serializing_if = "Option::is_none")]
99 // TODO: Add wrapper
100 unprioritize_translations: Option<&'a [&'a str]>,
101 /// Increases the priority of a certain type of translation. If you specify voice, voiceovers will be output first. If subtitles, subtitles will be output
102 #[serde(skip_serializing_if = "Option::is_none")]
103 prioritize_translation_type: Option<&'a [TranslationType]>,
104
105 /// 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
106 #[serde(skip_serializing_if = "Option::is_none")]
107 has_field: Option<&'a [MaterialDataField]>,
108 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
109 #[serde(skip_serializing_if = "Option::is_none")]
110 has_field_and: Option<&'a [MaterialDataField]>,
111
112 /// Deletes certain voices from the search results. IDs are listed separated by commas
113 #[serde(skip_serializing_if = "Option::is_none")]
114 block_translations: Option<&'a [u32]>,
115
116 /// Filtering materials by camrip parameter. If you specify false, only materials with a quality picture will be output. If you don't specify this parameter, all materials will be displayed
117 #[serde(skip_serializing_if = "Option::is_none")]
118 camrip: Option<bool>,
119 /// 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
120 #[serde(skip_serializing_if = "Option::is_none")]
121 lgbt: Option<bool>,
122
123 /// If you specify true, the seasons of the series will also be listed in the seasons field. This and the following parameter are made to avoid overloading the output with a huge amount of information about seasons and episodes, if this information is not needed for parsing
124 #[serde(skip_serializing_if = "Option::is_none")]
125 with_seasons: Option<bool>,
126
127 /// With this option you can specify which season you are interested in. This way, only shows that have that season will appear in the search results. Passing this parameter also automatically enables the with_seasons parameter
128 #[serde(skip_serializing_if = "Option::is_none")]
129 season: Option<&'a [u32]>,
130
131 /// If you specify true, the seasons field will be added to each series (even if with_seasons is not specified or specified as false) and the episodes field with the episodes of that season will be added to each season. If the with_episodes parameter is used, the series numbers will correspond to the normal series references. If you use the with_episodes_data parameter, episode objects will be assigned to the episode numbers, where the link will be available via the link parameter, the episode name (if any) via the title parameter, and the frames via screenshots
132 #[serde(skip_serializing_if = "Option::is_none")]
133 with_episodes: Option<bool>,
134 /// If you specify true, the seasons field will be added to each series (even if with_seasons is not specified or specified as false) and the episodes field with the episodes of that season will be added to each season. If the with_episodes parameter is used, the series numbers will correspond to the normal series references. If you use the with_episodes_data parameter, episode objects will be assigned to the episode numbers, where the link will be available via the link parameter, the episode name (if any) via the title parameter, and the frames via screenshots
135 #[serde(skip_serializing_if = "Option::is_none")]
136 with_episodes_data: Option<bool>,
137
138 /// With this option, you can specify which episode of a particular season you are interested in. Thus, only shows with that episode will appear in the search results. If you use this parameter, you must also pass the season parameter. Passing this parameter also automatically includes the with_episodes parameter
139 #[serde(skip_serializing_if = "Option::is_none")]
140 episode: Option<&'a [u32]>,
141
142 /// If you specify true, all links to players will be replaced by special links to pages with players (suitable for cases when you don't have your own site). You can customize appearance of these pages in settings in the base. If parameter with_seasons or with_episodes / with_episodes_data is specified together with this parameter, links in seasons and episodes will also be replaced
143 #[serde(skip_serializing_if = "Option::is_none")]
144 with_page_links: Option<bool>,
145
146 /// Filters materials by country in which they should not be blocked. The country codes are specified separated by commas
147 #[serde(skip_serializing_if = "Option::is_none")]
148 not_blocked_in: Option<&'a [&'a str]>,
149 /// A simpler analog of the previous parameter. Our server itself checks which country the current request comes from and doesn't display those materials that are blocked for that country. This parameter can be useful if the API is called on your site
150 #[serde(skip_serializing_if = "Option::is_none")]
151 not_blocked_for_me: Option<&'a [&'a str]>,
152
153 /// If you specify true, the material_data field will be added to each movie/series with information from Kinopoisk and Shikimori
154 #[serde(skip_serializing_if = "Option::is_none")]
155 with_material_data: Option<bool>,
156
157 /// 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
158 #[serde(skip_serializing_if = "Option::is_none")]
159 countries: Option<&'a [&'a str]>,
160
161 /// 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
162 #[serde(skip_serializing_if = "Option::is_none")]
163 genres: Option<&'a [&'a str]>,
164 /// 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
165 #[serde(skip_serializing_if = "Option::is_none")]
166 anime_genres: Option<&'a [&'a str]>,
167 /// 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
168 #[serde(skip_serializing_if = "Option::is_none")]
169 drama_genres: Option<&'a [&'a str]>,
170 /// 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
171 #[serde(skip_serializing_if = "Option::is_none")]
172 all_genres: Option<&'a [&'a str]>,
173
174 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
175 #[serde(skip_serializing_if = "Option::is_none")]
176 duration: Option<&'a [&'a str]>,
177
178 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
179 #[serde(skip_serializing_if = "Option::is_none")]
180 kinopoisk_rating: Option<&'a [&'a str]>,
181 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
182 #[serde(skip_serializing_if = "Option::is_none")]
183 imdb_rating: Option<&'a [&'a str]>,
184 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
185 #[serde(skip_serializing_if = "Option::is_none")]
186 shikimori_rating: Option<&'a [&'a str]>,
187 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
188 #[serde(skip_serializing_if = "Option::is_none")]
189 mydramalist_rating: Option<&'a [&'a str]>,
190
191 /// 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
192 #[serde(skip_serializing_if = "Option::is_none")]
193 actors: Option<&'a [&'a str]>,
194 /// 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
195 #[serde(skip_serializing_if = "Option::is_none")]
196 directors: Option<&'a [&'a str]>,
197 /// 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
198 #[serde(skip_serializing_if = "Option::is_none")]
199 producers: Option<&'a [&'a str]>,
200 /// 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
201 #[serde(skip_serializing_if = "Option::is_none")]
202 writers: Option<&'a [&'a str]>,
203 /// 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
204 #[serde(skip_serializing_if = "Option::is_none")]
205 composers: Option<&'a [&'a str]>,
206 /// 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
207 #[serde(skip_serializing_if = "Option::is_none")]
208 editors: Option<&'a [&'a str]>,
209 /// 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
210 #[serde(skip_serializing_if = "Option::is_none")]
211 designers: Option<&'a [&'a str]>,
212 /// 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
213 #[serde(skip_serializing_if = "Option::is_none")]
214 operators: Option<&'a [&'a str]>,
215
216 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
217 #[serde(skip_serializing_if = "Option::is_none")]
218 rating_mpaa: Option<&'a [MppaRating]>,
219
220 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
221 #[serde(skip_serializing_if = "Option::is_none")]
222 minimal_age: Option<&'a [&'a str]>,
223
224 /// 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)
225 #[serde(skip_serializing_if = "Option::is_none")]
226 anime_kind: Option<&'a [AnimeKind]>,
227
228 /// 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)
229 #[serde(skip_serializing_if = "Option::is_none")]
230 mydramalist_tags: Option<&'a [&'a str]>,
231
232 /// 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)
233 #[serde(skip_serializing_if = "Option::is_none")]
234 anime_status: Option<&'a [AnimeStatus]>,
235 /// 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)
236 #[serde(skip_serializing_if = "Option::is_none")]
237 drama_status: Option<&'a [DramaStatus]>,
238 /// 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)
239 #[serde(skip_serializing_if = "Option::is_none")]
240 all_status: Option<&'a [AllStatus]>,
241
242 /// 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)
243 #[serde(skip_serializing_if = "Option::is_none")]
244 anime_studios: Option<&'a [&'a str]>,
245 /// 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)
246 #[serde(skip_serializing_if = "Option::is_none")]
247 anime_licensed_by: Option<&'a [&'a str]>,
248}
249
250impl<'a> SearchQuery<'a> {
251 pub fn new() -> SearchQuery<'a> {
252 SearchQuery {
253 title: None,
254 title_orig: None,
255 strict: None,
256 full_match: None,
257 id: None,
258 player_link: None,
259 kinopoisk_id: None,
260 imdb_id: None,
261 mdl_id: None,
262 worldart_animation_id: None,
263 worldart_cinema_id: None,
264 worldart_link: None,
265 shikimori_id: None,
266 limit: None,
267 types: None,
268 year: None,
269 translation_id: None,
270 translation_type: None,
271 prioritize_translations: None,
272 unprioritize_translations: None,
273 prioritize_translation_type: None,
274 has_field: None,
275 has_field_and: None,
276 block_translations: None,
277 camrip: None,
278 lgbt: None,
279 with_seasons: None,
280 season: None,
281 with_episodes: None,
282 with_episodes_data: None,
283 episode: None,
284 with_page_links: None,
285 not_blocked_in: None,
286 not_blocked_for_me: None,
287 with_material_data: None,
288 countries: None,
289 genres: None,
290 anime_genres: None,
291 drama_genres: None,
292 all_genres: None,
293 duration: None,
294 kinopoisk_rating: None,
295 imdb_rating: None,
296 shikimori_rating: None,
297 mydramalist_rating: None,
298 actors: None,
299 directors: None,
300 producers: None,
301 writers: None,
302 composers: None,
303 editors: None,
304 designers: None,
305 operators: None,
306 rating_mpaa: None,
307 minimal_age: None,
308 anime_kind: None,
309 mydramalist_tags: None,
310 anime_status: None,
311 drama_status: None,
312 all_status: None,
313 anime_studios: None,
314 anime_licensed_by: None,
315 }
316 }
317
318 /// The name of the movie. It is not necessary to specify it explicitly, you can use a variant written by the user or a variant containing extra words. If you specify one of these parameters, the search will be performed on several fields at once: `title`, `title_orig`, `other_title`
319 pub fn with_title<'b>(&'b mut self, title: &'a str) -> &'b mut SearchQuery<'a> {
320 self.title = Some(title);
321 self
322 }
323 /// Original title. When this option is used, only the title_orig will be searched. It is not necessary to specify it explicitly, you can use a variant written by the user or a variant containing extra words
324 pub fn with_title_orig<'b>(&'b mut self, title_orig: &'a str) -> &'b mut SearchQuery<'a> {
325 self.title_orig = Some(title_orig);
326 self
327 }
328 /// If title or title_orig parameter was specified, this parameter defines the severity of checking if the title of the material corresponds to the search query. If true, the search results will show only those materials in which the word order is exactly the same as in the search query (but extra words in the search query are still allowed)
329 pub fn with_strict<'b>(&'b mut self, strict: bool) -> &'b mut SearchQuery<'a> {
330 self.strict = Some(strict);
331 self
332 }
333 /// If title or title_orig parameter was specified, this parameter defines the severity of checking if the title of the material corresponds to the search query. If true, the search results will only show content where the title completely matches the search query (no extra words, word order and presence of characters are also completely identical). The only thing the title may differ from the query is the case. When used in conjunction with the title, full consistency with at least one of the titles of the material is checked
334 pub fn with_full_match<'b>(&'b mut self, full_match: bool) -> &'b mut SearchQuery<'a> {
335 self.full_match = Some(full_match);
336 self
337 }
338
339 /// Search by Kodik ID
340 pub fn with_id<'b>(&'b mut self, id: &'a str) -> &'b mut SearchQuery<'a> {
341 self.id = Some(id);
342 self
343 }
344 /// Search for any link to the player
345 pub fn with_player_link<'b>(&'b mut self, player_link: &'a str) -> &'b mut SearchQuery<'a> {
346 self.player_link = Some(player_link);
347 self
348 }
349
350 /// Search by kinopoisk ID
351 pub fn with_kinopoisk_id<'b>(&'b mut self, kinopoisk_id: &'a str) -> &'b mut SearchQuery<'a> {
352 self.kinopoisk_id = Some(kinopoisk_id);
353 self
354 }
355 /// Search by IMDb ID
356 pub fn with_imdb_id<'b>(&'b mut self, imdb_id: &'a str) -> &'b mut SearchQuery<'a> {
357 self.imdb_id = Some(imdb_id);
358 self
359 }
360 /// Search by MyDramaList ID
361 pub fn with_mdl_id<'b>(&'b mut self, mdl_id: &'a str) -> &'b mut SearchQuery<'a> {
362 self.mdl_id = Some(mdl_id);
363 self
364 }
365
366 /// Search for World Art IDs in the anime section (World Art has different content sections, each with their own independent IDs)
367 pub fn with_worldart_animation_id<'b>(
368 &'b mut self,
369 worldart_animation_id: &'a str,
370 ) -> &'b mut SearchQuery<'a> {
371 self.worldart_animation_id = Some(worldart_animation_id);
372 self
373 }
374 /// Search for World Art IDs in the Movies section
375 pub fn with_worldart_cinema_id<'b>(
376 &'b mut self,
377 worldart_cinema_id: &'a str,
378 ) -> &'b mut SearchQuery<'a> {
379 self.worldart_cinema_id = Some(worldart_cinema_id);
380 self
381 }
382 /// Search the full World Art link
383 pub fn with_worldart_link<'b>(&'b mut self, worldart_link: &'a str) -> &'b mut SearchQuery<'a> {
384 self.worldart_link = Some(worldart_link);
385 self
386 }
387 /// Search by Shikimori ID
388 pub fn with_shikimori_id<'b>(&'b mut self, shikimori_id: &'a str) -> &'b mut SearchQuery<'a> {
389 self.shikimori_id = Some(shikimori_id);
390 self
391 }
392
393 /// Maximum number of outputs
394 pub fn with_limit<'b>(&'b mut self, limit: u32) -> &'b mut SearchQuery<'a> {
395 self.limit = Some(limit);
396 self
397 }
398
399 /// 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
400 pub fn with_types<'b>(&'b mut self, types: &'a [ReleaseType]) -> &'b mut SearchQuery<'a> {
401 self.types = Some(types);
402 self
403 }
404
405 ///Filter materials by year If you set this parameter, only materials of the corresponding year will be displayed
406 pub fn with_year<'b>(&'b mut self, year: &'a [u32]) -> &'b mut SearchQuery<'a> {
407 self.year = Some(year);
408 self
409 }
410
411 /// Filtering materials by translation ID
412 pub fn with_translation_id<'b>(
413 &'b mut self,
414 translation_id: &'a [u32],
415 ) -> &'b mut SearchQuery<'a> {
416 self.translation_id = Some(translation_id);
417 self
418 }
419 /// Filter content by translation type. Allows you to output only voice translation or only subtitles
420 pub fn with_translation_type<'b>(
421 &'b mut self,
422 translation_type: &'a [TranslationType],
423 ) -> &'b mut SearchQuery<'a> {
424 self.translation_type = Some(translation_type);
425 self
426 }
427
428 /// 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
429 pub fn with_has_field<'b>(
430 &'b mut self,
431 has_field: &'a [MaterialDataField],
432 ) -> &'b mut SearchQuery<'a> {
433 self.has_field = Some(has_field);
434 self
435 }
436 /// Filtering materials based on the presence of a specific field. Materials that have all the listed fields are shown
437 pub fn with_has_field_and<'b>(
438 &'b mut self,
439 has_field: &'a [MaterialDataField],
440 ) -> &'b mut SearchQuery<'a> {
441 self.has_field_and = Some(has_field);
442 self
443 }
444
445 /// Increases the priority of certain voices. The IDs are listed in commas. The "leftmost" ID, the higher its priority. IDs of all voices can be received through API resource /translations or on the page of list of voices. Standard priority of dubbed and prof. Multivoiced". To deactivate standard priority you need to pass value 0. You can also specify the translation type (subtitles/voice) instead of the ID
446 // TODO: Add wrapper
447 pub fn with_prioritize_translations<'b>(
448 &'b mut self,
449 prioritize_translations: &'a [&'a str],
450 ) -> &'b mut SearchQuery<'a> {
451 self.prioritize_translations = Some(prioritize_translations);
452 self
453 }
454 /// Decreases the priority of certain voices. The IDs are listed in commas. The "leftmost" ID, the lower its priority. IDs of all voices can be received through API resource /translations or on page of voices list. Standard priority of soundtracks "Ukrainian", "English" and all subtitles are lowered. To deactivate standard priority you need to pass value 0. You can also specify the translation type (subtitles/voice) instead of the ID
455 // TODO: Add wrapper
456 pub fn with_unprioritize_translations<'b>(
457 &'b mut self,
458 unprioritize_translations: &'a [&'a str],
459 ) -> &'b mut SearchQuery<'a> {
460 self.unprioritize_translations = Some(unprioritize_translations);
461 self
462 }
463 /// Increases the priority of a certain type of translation. If you specify voice, voiceovers will be output first. If subtitles, subtitles will be output
464 pub fn with_prioritize_translation_type<'b>(
465 &'b mut self,
466 prioritize_translation_type: &'a [TranslationType],
467 ) -> &'b mut SearchQuery<'a> {
468 self.prioritize_translation_type = Some(prioritize_translation_type);
469 self
470 }
471
472 /// Deletes certain voices from the search results. IDs are listed separated by commas
473 pub fn with_block_translations<'b>(
474 &'b mut self,
475 block_translations: &'a [u32],
476 ) -> &'b mut SearchQuery<'a> {
477 self.block_translations = Some(block_translations);
478 self
479 }
480
481 /// Filtering materials by camrip parameter. If you specify false, only materials with a quality picture will be output. If you don't specify this parameter, all materials will be displayed
482 pub fn with_camrip<'b>(&'b mut self, camrip: bool) -> &'b mut SearchQuery<'a> {
483 self.camrip = Some(camrip);
484 self
485 }
486 /// 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
487 pub fn with_lgbt<'b>(&'b mut self, lgbt: bool) -> &'b mut SearchQuery<'a> {
488 self.lgbt = Some(lgbt);
489 self
490 }
491
492 /// If you specify true, the seasons of the series will also be listed in the seasons field. This and the following parameter are made to avoid overloading the output with a huge amount of information about seasons and episodes, if this information is not needed for parsing
493 pub fn with_seasons<'b>(&'b mut self, with_seasons: bool) -> &'b mut SearchQuery<'a> {
494 self.with_seasons = Some(with_seasons);
495 self
496 }
497
498 /// With this option you can specify which season you are interested in. This way, only shows that have that season will appear in the search results. Passing this parameter also automatically enables the with_seasons parameter
499 pub fn with_season<'b>(&'b mut self, season: &'a [u32]) -> &'b mut SearchQuery<'a> {
500 self.season = Some(season);
501 self
502 }
503
504 /// If you specify true, the seasons field will be added to each series (even if with_seasons is not specified or specified as false) and the episodes field with the episodes of that season will be added to each season. If the with_episodes parameter is used, the series numbers will correspond to the normal series references. If you use the with_episodes_data parameter, episode objects will be assigned to the episode numbers, where the link will be available via the link parameter, the episode name (if any) via the title parameter, and the frames via screenshots
505 pub fn with_episodes<'b>(&'b mut self, with_episodes: bool) -> &'b mut SearchQuery<'a> {
506 self.with_episodes = Some(with_episodes);
507 self
508 }
509 /// If you specify true, the seasons field will be added to each series (even if with_seasons is not specified or specified as false) and the episodes field with the episodes of that season will be added to each season. If the with_episodes parameter is used, the series numbers will correspond to the normal series references. If you use the with_episodes_data parameter, episode objects will be assigned to the episode numbers, where the link will be available via the link parameter, the episode name (if any) via the title parameter, and the frames via screenshots
510 pub fn with_episodes_data<'b>(
511 &'b mut self,
512 with_episodes_data: bool,
513 ) -> &'b mut SearchQuery<'a> {
514 self.with_episodes_data = Some(with_episodes_data);
515 self
516 }
517
518 /// With this option, you can specify which episode of a particular season you are interested in. Thus, only shows with that episode will appear in the search results. If you use this parameter, you must also pass the season parameter. Passing this parameter also automatically includes the with_episodes parameter
519 pub fn with_episode<'b>(&'b mut self, episode: &'a [u32]) -> &'b mut SearchQuery<'a> {
520 self.episode = Some(episode);
521 self
522 }
523
524 /// If you specify true, all links to players will be replaced by special links to pages with players (suitable for cases when you don't have your own site). You can customize appearance of these pages in settings in the base. If parameter with_seasons or with_episodes / with_episodes_data is specified together with this parameter, links in seasons and episodes will also be replaced
525 pub fn with_page_links<'b>(&'b mut self, with_page_links: bool) -> &'b mut SearchQuery<'a> {
526 self.with_page_links = Some(with_page_links);
527 self
528 }
529
530 /// Filters materials by country in which they should not be blocked. The country codes are specified separated by commas
531 pub fn with_not_blocked_in<'b>(
532 &'b mut self,
533 not_blocked_in: &'a [&'a str],
534 ) -> &'b mut SearchQuery<'a> {
535 self.not_blocked_in = Some(not_blocked_in);
536 self
537 }
538 /// A simpler analog of the previous parameter. Our server itself checks which country the current request comes from and doesn't display those materials that are blocked for that country. This parameter can be useful if the API is called on your site
539 pub fn with_not_blocked_for_me<'b>(
540 &'b mut self,
541 not_blocked_for_me: &'a [&'a str],
542 ) -> &'b mut SearchQuery<'a> {
543 self.not_blocked_for_me = Some(not_blocked_for_me);
544 self
545 }
546 /// If you specify true, the material_data field will be added to each movie/series with information from Kinopoisk and Shikimori
547 pub fn with_material_data<'b>(
548 &'b mut self,
549 with_material_data: bool,
550 ) -> &'b mut SearchQuery<'a> {
551 self.with_material_data = Some(with_material_data);
552 self
553 }
554
555 /// 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
556 pub fn with_countries<'b>(&'b mut self, countries: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
557 self.countries = Some(countries);
558 self
559 }
560
561 /// 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
562 pub fn with_genres<'b>(&'b mut self, genres: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
563 self.genres = Some(genres);
564 self
565 }
566 /// 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
567 pub fn with_anime_genres<'b>(
568 &'b mut self,
569 anime_genres: &'a [&'a str],
570 ) -> &'b mut SearchQuery<'a> {
571 self.anime_genres = Some(anime_genres);
572 self
573 }
574 /// 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
575 pub fn with_drama_genres<'b>(
576 &'b mut self,
577 drama_genres: &'a [&'a str],
578 ) -> &'b mut SearchQuery<'a> {
579 self.drama_genres = Some(drama_genres);
580 self
581 }
582 /// 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
583 pub fn with_all_genres<'b>(&'b mut self, all_genres: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
584 self.all_genres = Some(all_genres);
585 self
586 }
587
588 /// Filtering by duration (in minutes). You can specify either a single value to search for the exact duration, or an interval.
589 pub fn with_duration<'b>(&'b mut self, duration: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
590 self.duration = Some(duration);
591 self
592 }
593
594 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
595 pub fn with_kinopoisk_rating<'b>(
596 &'b mut self,
597 kinopoisk_rating: &'a [&'a str],
598 ) -> &'b mut SearchQuery<'a> {
599 self.kinopoisk_rating = Some(kinopoisk_rating);
600 self
601 }
602 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
603 pub fn with_imdb_rating<'b>(
604 &'b mut self,
605 imdb_rating: &'a [&'a str],
606 ) -> &'b mut SearchQuery<'a> {
607 self.imdb_rating = Some(imdb_rating);
608 self
609 }
610 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
611 pub fn with_shikimori_rating<'b>(
612 &'b mut self,
613 shikimori_rating: &'a [&'a str],
614 ) -> &'b mut SearchQuery<'a> {
615 self.shikimori_rating = Some(shikimori_rating);
616 self
617 }
618 /// Filtering by Kinopoisk, IMDb, Shikimori, or MyDramaList ratings. You can specify either a single value to search for the exact rating, or an interval
619 pub fn with_mydramalist_rating<'b>(
620 &'b mut self,
621 mydramalist_rating: &'a [&'a str],
622 ) -> &'b mut SearchQuery<'a> {
623 self.mydramalist_rating = Some(mydramalist_rating);
624 self
625 }
626
627 /// 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
628 pub fn with_actors<'b>(&'b mut self, actors: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
629 self.actors = Some(actors);
630 self
631 }
632 /// 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
633 pub fn with_directors<'b>(&'b mut self, directors: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
634 self.directors = Some(directors);
635 self
636 }
637 /// 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
638 pub fn with_producers<'b>(&'b mut self, producers: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
639 self.producers = Some(producers);
640 self
641 }
642 /// 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
643 pub fn with_writers<'b>(&'b mut self, writers: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
644 self.writers = Some(writers);
645 self
646 }
647 /// 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
648 pub fn with_composers<'b>(&'b mut self, composers: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
649 self.composers = Some(composers);
650 self
651 }
652 /// 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
653 pub fn with_editors<'b>(&'b mut self, editors: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
654 self.editors = Some(editors);
655 self
656 }
657 /// 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
658 pub fn with_designers<'b>(&'b mut self, designers: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
659 self.designers = Some(designers);
660 self
661 }
662 /// 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
663 pub fn with_operators<'b>(&'b mut self, operators: &'a [&'a str]) -> &'b mut SearchQuery<'a> {
664 self.operators = Some(operators);
665 self
666 }
667
668 /// Filtering materials by age rating. You can specify a single value or multiple values, separated by commas. The parameter is case-insensitive
669 pub fn with_rating_mpaa<'b>(
670 &'b mut self,
671 rating_mpaa: &'a [MppaRating],
672 ) -> &'b mut SearchQuery<'a> {
673 self.rating_mpaa = Some(rating_mpaa);
674 self
675 }
676
677 /// Filter content by the minimum age from which it can be viewed. You can specify either a single value or a range of values
678 pub fn with_minimal_age<'b>(
679 &'b mut self,
680 minimal_age: &'a [&'a str],
681 ) -> &'b mut SearchQuery<'a> {
682 self.minimal_age = Some(minimal_age);
683 self
684 }
685
686 /// 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)
687 pub fn with_anime_kind<'b>(
688 &'b mut self,
689 anime_kind: &'a [AnimeKind],
690 ) -> &'b mut SearchQuery<'a> {
691 self.anime_kind = Some(anime_kind);
692 self
693 }
694
695 /// 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)
696 pub fn with_mydramalist_tags<'b>(
697 &'b mut self,
698 mydramalist_tags: &'a [&'a str],
699 ) -> &'b mut SearchQuery<'a> {
700 self.mydramalist_tags = Some(mydramalist_tags);
701 self
702 }
703
704 /// 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)
705 pub fn with_anime_status<'b>(
706 &'b mut self,
707 anime_status: &'a [AnimeStatus],
708 ) -> &'b mut SearchQuery<'a> {
709 self.anime_status = Some(anime_status);
710 self
711 }
712 /// 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)
713 pub fn with_drama_status<'b>(
714 &'b mut self,
715 drama_status: &'a [DramaStatus],
716 ) -> &'b mut SearchQuery<'a> {
717 self.drama_status = Some(drama_status);
718 self
719 }
720 /// 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)
721 pub fn with_all_status<'b>(
722 &'b mut self,
723 all_status: &'a [AllStatus],
724 ) -> &'b mut SearchQuery<'a> {
725 self.all_status = Some(all_status);
726 self
727 }
728
729 /// 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)
730 pub fn with_anime_studios<'b>(
731 &'b mut self,
732 anime_studios: &'a [&'a str],
733 ) -> &'b mut SearchQuery<'a> {
734 self.anime_studios = Some(anime_studios);
735 self
736 }
737 /// 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)
738 pub fn with_anime_licensed_by<'b>(
739 &'b mut self,
740 anime_licensed_by: &'a [&'a str],
741 ) -> &'b mut SearchQuery<'a> {
742 self.anime_licensed_by = Some(anime_licensed_by);
743 self
744 }
745
746 /// Execute the query and fetch the results.
747 pub async fn execute<'b>(&'a self, client: &'b Client) -> Result<SearchResponse, Error> {
748 let payload = serialize_into_query_parts(self)?;
749
750 let response = client
751 .init_post_request("/search")
752 .query(&payload)
753 .send()
754 .await
755 .map_err(Error::HttpError)?;
756
757 let result = response
758 .json::<SearchResponseUnion>()
759 .await
760 .map_err(Error::HttpError)?;
761
762 match result {
763 SearchResponseUnion::Result(result) => Ok(result),
764 SearchResponseUnion::Error { error } => Err(Error::KodikError(error)),
765 }
766 }
767}
768
769impl<'a> Default for SearchQuery<'a> {
770 fn default() -> Self {
771 Self::new()
772 }
773}