use crate::{
genre::Genre,
interface::{AgeCategory, WorkType},
DlsiteClient, Result,
};
use chrono::NaiveDate;
pub mod ajax;
pub mod html;
pub mod review;
#[cfg(test)]
mod test;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Product {
pub id: String,
pub title: String,
pub work_type: WorkType,
pub released_at: NaiveDate,
pub age_rating: Option<AgeCategory>,
pub genre: Vec<Genre>,
pub circle_id: String,
pub circle_name: String,
pub price: i32,
pub series: Option<String>,
pub sale_count: Option<i32>,
pub review_count: Option<i32>,
pub rating: Option<f32>,
pub rate_count: Option<i32>,
pub images: Vec<String>,
pub people: ProductPeople,
pub reviewer_genre: Vec<(Genre, i32)>,
pub file_format: Vec<String>,
pub file_size: Option<String>,
pub product_format: Vec<String>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ProductPeople {
pub author: Option<Vec<String>>,
pub scenario: Option<Vec<String>>,
pub illustrator: Option<Vec<String>>,
pub voice_actor: Option<Vec<String>>,
}
impl DlsiteClient {
pub async fn get_product(&self, product_id: &str) -> Result<Product> {
let (html_data, ajax_data, review_data) = tokio::try_join!(
self.get_product_html(product_id),
self.get_product_ajax(product_id),
self.get_product_review(product_id, 6, 1, true, review::ReviewSortOrder::New)
)?;
Ok(Product {
id: product_id.to_string(),
title: ajax_data.work_name,
work_type: ajax_data.work_type,
released_at: html_data.released_at,
age_rating: html_data.age_rating,
genre: html_data.genre,
series: html_data.series,
circle_name: html_data.circle_name,
circle_id: html_data.circle_id,
price: ajax_data.price,
rating: ajax_data.rate_average_2dp,
rate_count: ajax_data.rate_count,
sale_count: ajax_data.dl_count,
review_count: ajax_data.review_count,
images: html_data.images,
people: html_data.people,
reviewer_genre: review_data.reviewer_genre_list.unwrap_or_default(),
file_format: html_data.file_format,
file_size: html_data.file_size,
product_format: html_data.product_format,
})
}
}