1use crate::constants::{methods, urls};
2
3use serde::{Deserialize, Deserializer, Serialize};
4use std::collections::HashMap;
5
6use log::info;
7
8use crate::IopClient;
9
10#[derive(Serialize, Deserialize, Debug)]
11pub struct NewCategoryResponse {
12 pub alibaba_icbu_category_get_new_response: NewCategoryGroup,
13 pub request_id: Option<String>,
14 pub _trace_id_: Option<String>,
15}
16
17#[derive(Serialize, Deserialize, Debug)]
18pub struct NewCategoryGroup {
19 pub category: NewCategory,
20}
21
22#[derive(Serialize, Deserialize, Debug)]
23pub struct NewCategory {
24 pub leaf_category: bool,
25 pub cn_name: Option<String>,
26 pub category_id: i32,
27 pub level: i32,
28 pub name: String,
29
30 #[serde(default, deserialize_with = "empty_object_as_none")]
31 pub child_ids: Option<NewCategoryChildId>,
32
33 #[serde(default, deserialize_with = "empty_object_as_none")]
34 pub parent_ids: Option<NewCategoryChildId>,
35}
36
37#[derive(Serialize, Deserialize, Debug)]
38pub struct NewCategoryChildId {
39 pub number: Vec<String>,
40}
41
42#[derive(Serialize, Deserialize, Debug)]
43struct CategoryAttributeGetResponse {
44 alibaba_icbu_category_attribute_get_response: CategoryAttributeGroup,
45}
46
47#[derive(Serialize, Deserialize, Debug)]
48pub struct CategoryAttributeGroup {
49 pub attributes: CategoryAttributes,
50 request_id: Option<String>,
51 _trace_id_: Option<String>,
52}
53
54#[derive(Serialize, Deserialize, Debug)]
55pub struct CategoryAttributes {
56 pub attribute: Vec<CategoryAttribute>,
57}
58
59#[derive(Serialize, Deserialize, Debug)]
60pub struct CategoryAttribute {
61 pub sku_attribute: bool,
62 pub show_type: String,
63 pub customize_image: bool,
64 pub car_model: bool,
65 pub value_type: String,
66 pub customize_value: bool,
67
68 #[serde(deserialize_with = "empty_object_as_none")]
69 pub attribute_values: Option<AttributeValues>,
70 pub input_type: String,
71 pub en_name: String,
72 pub required: bool,
73 pub attr_id: i32,
74}
75
76#[derive(Serialize, Deserialize, Debug)]
77pub struct AttributeValues {
78 pub attribute_value: Vec<AttributeValue>,
79}
80
81#[derive(Serialize, Deserialize, Debug)]
82pub struct AttributeValue {
83 pub sku_value: bool,
84 pub attr_value_id: i32,
85 pub en_name: String,
86}
87
88fn empty_object_as_none<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
90where
91 D: Deserializer<'de>,
92 T: Deserialize<'de>,
93{
94 #[derive(Deserialize)]
95 #[serde(
96 untagged,
97 deny_unknown_fields,
98 expecting = "object, empty object or null"
99 )]
100 enum Helper<T> {
101 Empty {},
102 Data(T),
103 Null,
104 }
105 match Helper::deserialize(deserializer) {
106 Ok(Helper::Data(data)) => Ok(Some(data)),
107 Ok(_) => Ok(None),
108 Err(e) => Err(e),
109 }
110}
111
112impl IopClient {
113 pub async fn list_product_categories(
132 &self,
133 cat_id: i32,
134 ) -> Result<NewCategory, Box<dyn std::error::Error>> {
135 let mut map = HashMap::new();
136 map.insert("cat_id".to_string(), format!("{}", cat_id));
137 map.insert(
138 "method".to_string(),
139 methods::ALIBABA_ICBU_CATEGORY_GET_NEW.to_string(),
140 );
141
142 let params = self.build_request_params(map).await;
143
144 let hash = self.generate_sign(None, params.clone());
145 let url = self.generate_url(urls::BASE_SYNC_URL.to_string(), params.clone(), hash);
146 info!("--------list_product_categories-------- url: {:#?}", url);
147
148 let response = self.client.get(&url).send().await?;
149 let result = response.json::<NewCategoryResponse>().await?;
150
151 Ok(result.alibaba_icbu_category_get_new_response.category)
152 }
153
154 pub async fn get_category_attributes(
173 self,
174 cat_id: i32,
175 ) -> Result<CategoryAttributeGroup, Box<dyn std::error::Error>> {
176 let mut map = HashMap::new();
177 map.insert("cat_id".to_string(), format!("{}", cat_id));
178 map.insert(
179 "method".to_string(),
180 methods::ALIBABA_ICBU_CATEGORY_ATTRIBUTE_GET.to_string(),
181 );
182
183 let params = self.build_request_params(map).await;
184
185 let hash = self.generate_sign(None, params.clone());
186 let url = self.generate_url(urls::BASE_SYNC_URL.to_string(), params.clone(), hash);
187 info!("--------get_category_attributes-------- url: {:#?}", url);
188
189 let response = self.client.get(&url).send().await?;
190 let result = response.json::<CategoryAttributeGetResponse>().await?;
191
192 Ok(result.alibaba_icbu_category_attribute_get_response)
193 }
194}