dmm_api/
actress_search.rs

1use std::fmt::Display;
2use std::str::FromStr;
3
4use chrono::NaiveDate;
5use serde::{de, Deserialize, Deserializer, Serialize};
6
7use crate::dmm::{ApiResult, ElementVec};
8
9#[derive(Serialize, Debug, Default)]
10pub struct ActressSearchParams {
11    pub initial: Option<char>,
12    pub actress_id: Option<String>,
13    pub keyword: Option<String>,
14    pub gte_bust: Option<i64>,
15    pub lte_bust: Option<i64>,
16    pub gte_waist: Option<i64>,
17    pub lte_waist: Option<i64>,
18    pub gte_hip: Option<i64>,
19    pub lte_hip: Option<i64>,
20    pub gte_height: Option<i64>,
21    pub lte_height: Option<i64>,
22    pub gte_birthday: Option<NaiveDate>,
23    pub lte_birthday: Option<NaiveDate>,
24    pub hits: Option<i64>,
25    pub offset: Option<i64>,
26    pub sort: Option<SortValue>,
27}
28
29#[derive(Serialize, Debug)]
30pub enum SortValue {
31    #[serde(rename = "name")]
32    Name,
33    #[serde(rename = "-name")]
34    NameDesc,
35    #[serde(rename = "bust")]
36    Bust,
37    #[serde(rename = "-bust")]
38    BustDesc,
39    #[serde(rename = "waist")]
40    Waist,
41    #[serde(rename = "-waist")]
42    WaistDesc,
43    #[serde(rename = "hip")]
44    Hip,
45    #[serde(rename = "-hip")]
46    HipDesc,
47    #[serde(rename = "height")]
48    Height,
49    #[serde(rename = "-height")]
50    HeightDesc,
51    #[serde(rename = "birthday")]
52    Birthday,
53    #[serde(rename = "-birthday")]
54    BirthdayDesc,
55    #[serde(rename = "id")]
56    Id,
57    #[serde(rename = "-id")]
58    IdDesc,
59}
60
61#[derive(Deserialize, Debug)]
62pub struct ActressSearchResult {
63    pub status: String,
64    pub result_count: i64,
65    pub total_count: i64,
66    pub first_position: i64,
67    pub actress: Option<ElementVec<Actress>>,
68}
69impl ApiResult for ActressSearchResult {}
70
71#[derive(Deserialize, Debug)]
72pub struct Actress {
73    pub id: String,
74    pub name: String,
75    pub ruby: String,
76    pub bust: Option<String>,
77    pub cup: Option<String>,
78    #[serde(deserialize_with = "val_deserializer")]
79    pub waist: Option<i64>,
80    #[serde(deserialize_with = "val_deserializer")]
81    pub hip: Option<i64>,
82    #[serde(deserialize_with = "val_deserializer")]
83    pub height: Option<i64>,
84    #[serde(deserialize_with = "val_deserializer")]
85    pub birthday: Option<NaiveDate>,
86    pub blood_type: Option<String>,
87    pub hobby: Option<String>,
88    pub prefectures: Option<String>,
89    #[serde(rename = "imageURL")]
90    pub image_url: Option<ImageUrl>,
91    #[serde(rename = "listURL")]
92    pub list_url: ListUrl,
93}
94
95#[derive(Deserialize, Debug)]
96pub struct ImageUrl {
97    pub small: String,
98    pub large: String,
99}
100
101#[derive(Deserialize, Debug)]
102pub struct ListUrl {
103    pub digital: String,
104    pub monthly: String,
105    pub mono: String,
106    pub rental: String,
107}
108
109fn val_deserializer<'de, D, T>(d: D) -> Result<Option<T>, D::Error>
110where
111    D: Deserializer<'de>,
112    T: FromStr,
113    <T as FromStr>::Err: Display,
114{
115    let s = String::deserialize(d)?;
116    if s.is_empty() {
117        Ok(None)
118    } else {
119        s.parse::<T>().map(Some).map_err(de::Error::custom)
120    }
121}