use std::fmt::Display;
use std::str::FromStr;
use chrono::NaiveDate;
use serde::{de, Deserialize, Deserializer, Serialize};
use crate::dmm::{ApiResult, ElementVec};
#[derive(Serialize, Debug, Default)]
pub struct ActressSearchParams {
pub initial: Option<char>,
pub actress_id: Option<String>,
pub keyword: Option<String>,
pub gte_bust: Option<i64>,
pub lte_bust: Option<i64>,
pub gte_waist: Option<i64>,
pub lte_waist: Option<i64>,
pub gte_hip: Option<i64>,
pub lte_hip: Option<i64>,
pub gte_height: Option<i64>,
pub lte_height: Option<i64>,
pub gte_birthday: Option<NaiveDate>,
pub lte_birthday: Option<NaiveDate>,
pub hits: Option<i64>,
pub offset: Option<i64>,
pub sort: Option<SortValue>,
}
#[derive(Serialize, Debug)]
pub enum SortValue {
#[serde(rename = "name")]
Name,
#[serde(rename = "-name")]
NameDesc,
#[serde(rename = "bust")]
Bust,
#[serde(rename = "-bust")]
BustDesc,
#[serde(rename = "waist")]
Waist,
#[serde(rename = "-waist")]
WaistDesc,
#[serde(rename = "hip")]
Hip,
#[serde(rename = "-hip")]
HipDesc,
#[serde(rename = "height")]
Height,
#[serde(rename = "-height")]
HeightDesc,
#[serde(rename = "birthday")]
Birthday,
#[serde(rename = "-birthday")]
BirthdayDesc,
#[serde(rename = "id")]
Id,
#[serde(rename = "-id")]
IdDesc,
}
#[derive(Deserialize, Debug)]
pub struct ActressSearchResult {
pub status: String,
pub result_count: i64,
pub total_count: i64,
pub first_position: i64,
pub actress: Option<ElementVec<Actress>>,
}
impl ApiResult for ActressSearchResult {}
#[derive(Deserialize, Debug)]
pub struct Actress {
pub id: String,
pub name: String,
pub ruby: String,
pub bust: Option<String>,
pub cup: Option<String>,
#[serde(deserialize_with = "val_deserializer")]
pub waist: Option<i64>,
#[serde(deserialize_with = "val_deserializer")]
pub hip: Option<i64>,
#[serde(deserialize_with = "val_deserializer")]
pub height: Option<i64>,
#[serde(deserialize_with = "val_deserializer")]
pub birthday: Option<NaiveDate>,
pub blood_type: Option<String>,
pub hobby: Option<String>,
pub prefectures: Option<String>,
#[serde(rename = "imageURL")]
pub image_url: Option<ImageUrl>,
#[serde(rename = "listURL")]
pub list_url: ListUrl,
}
#[derive(Deserialize, Debug)]
pub struct ImageUrl {
pub small: String,
pub large: String,
}
#[derive(Deserialize, Debug)]
pub struct ListUrl {
pub digital: String,
pub monthly: String,
pub mono: String,
}
fn val_deserializer<'de, D, T>(d: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
T: FromStr,
<T as FromStr>::Err: Display,
{
let s = String::deserialize(d)?;
if s.is_empty() {
Ok(None)
} else {
s.parse::<T>().map(Some).map_err(de::Error::custom)
}
}