1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use std::collections::HashMap;

use serde::{Deserialize, Deserializer};

use crate::{DlsiteClient, DlsiteError, Result};

use super::WorkType;

/// Data of a product from the AJAX API.
#[derive(Debug, Clone, Deserialize)]
pub struct ProductAjax {
    pub maker_id: String,
    #[serde(deserialize_with = "serde_aux::prelude::deserialize_number_from_string")]
    pub dl_count: i32,
    #[serde(deserialize_with = "serde_aux::prelude::deserialize_option_number_from_string")]
    pub review_count: Option<i32>,
    pub rate_average_2dp: Option<f32>,
    pub rate_count: Option<i32>,
    pub work_name: String,
    pub price: i32,
    #[serde(deserialize_with = "deserialize_work_type")]
    pub work_type: WorkType,
}

fn deserialize_work_type<'de, D>(deserializer: D) -> std::result::Result<WorkType, D::Error>
where
    D: Deserializer<'de>,
{
    let s: String = Deserialize::deserialize(deserializer)?;

    Ok(match &*s {
        "SOU" => WorkType::Voice,
        _ => WorkType::Unknown,
    })
}

impl DlsiteClient {
    /// Get the AJAX data of multiple products.
    pub async fn get_products_ajax(
        &self,
        product_ids: Vec<&str>,
    ) -> Result<HashMap<String, ProductAjax>> {
        let path = format!("/product/info/ajax?product_id={}", product_ids.join(","));
        let ajax_json_str = self.get(&path).await?;

        let json: HashMap<String, ProductAjax> = serde_json::from_str(&ajax_json_str)?;

        Ok(json)
    }
    /// Get the AJAX data of a product.
    pub async fn get_product_ajax(&self, product_id: &str) -> Result<ProductAjax> {
        let path = format!("/product/info/ajax?product_id={}", product_id);
        let ajax_json_str = self.get(&path).await?;

        let mut json: HashMap<String, ProductAjax> = serde_json::from_str(&ajax_json_str)?;
        let product = json
            .remove(product_id)
            .ok_or_else(|| DlsiteError::ParseError("Failed to parse ajax json".to_string()))?;

        Ok(product)
    }
}