use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct PddConvertResponse {
#[serde(default, rename = "goods_zs_unit_generate_response")]
pub response: Option<PddConvertResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddConvertResult {
#[serde(default)]
pub multi_group_mobile_short_url: Option<String>,
#[serde(default)]
pub multi_group_url: Option<String>,
#[serde(default)]
pub mobile_url: Option<String>,
#[serde(default)]
pub multi_group_short_url: Option<String>,
#[serde(default)]
pub mobile_short_url: Option<String>,
#[serde(default)]
pub multi_group_mobile_url: Option<String>,
#[serde(default)]
pub request_id: Option<String>,
#[serde(default)]
pub url: Option<String>,
#[serde(default)]
pub short_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailSimpleResponse {
#[serde(default, rename = "goods_basic_detail_response")]
pub response: Option<PddGoodsBasicDetailResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsBasicDetailResult {
#[serde(default)]
pub goods_list: Option<Vec<PddGoodsBasicItem>>,
#[serde(default)]
pub request_id: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsBasicItem {
#[serde(default)]
pub goods_name: Option<String>,
#[serde(default)]
pub goods_pic: Option<String>,
#[serde(default)]
pub min_normal_price: Option<i64>,
#[serde(default)]
pub goods_id: Option<i64>,
#[serde(default)]
pub min_group_price: Option<i64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailFullResponse {
#[serde(default, rename = "goods_search_response")]
pub response: Option<PddGoodsSearchResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsSearchResult {
#[serde(default)]
pub goods_list: Option<Vec<PddGoodsDetailItem>>,
#[serde(default)]
pub request_id: Option<String>,
#[serde(default)]
pub total_count: Option<i64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailItem {
#[serde(default)]
pub goods_id: Option<i64>,
#[serde(default)]
pub goods_name: Option<String>,
#[serde(default)]
pub goods_desc: Option<String>,
#[serde(default)]
pub goods_thumbnail_url: Option<String>,
#[serde(default)]
pub goods_image_url: Option<String>,
#[serde(default)]
pub goods_gallery_urls: Option<Vec<String>>,
#[serde(default)]
pub min_normal_price: Option<i64>,
#[serde(default)]
pub min_group_price: Option<i64>,
#[serde(default)]
pub sales_tip: Option<String>,
#[serde(default)]
pub promotion_rate: Option<i64>,
#[serde(default)]
pub coupon_discount: Option<i64>,
#[serde(default)]
pub coupon_min_order_amount: Option<i64>,
#[serde(default)]
pub coupon_remain_quantity: Option<i64>,
#[serde(default)]
pub coupon_total_quantity: Option<i64>,
#[serde(default)]
pub coupon_start_time: Option<i64>,
#[serde(default)]
pub coupon_end_time: Option<i64>,
#[serde(default)]
pub mall_id: Option<i64>,
#[serde(default)]
pub mall_name: Option<String>,
#[serde(default)]
pub merchant_type: Option<i32>,
#[serde(default)]
pub cat_id: Option<i64>,
#[serde(default)]
pub cat_name: Option<String>,
#[serde(default, rename = "cat_id_1")]
pub cat_id1: Option<i64>,
#[serde(default, rename = "cat_id_2")]
pub cat_id2: Option<i64>,
#[serde(default, rename = "cat_id_3")]
pub cat_id3: Option<i64>,
#[serde(default, rename = "cat_name_1")]
pub cat_name1: Option<String>,
#[serde(default, rename = "cat_name_2")]
pub cat_name2: Option<String>,
#[serde(default, rename = "cat_name_3")]
pub cat_name3: Option<String>,
#[serde(default)]
pub has_coupon: Option<bool>,
#[serde(default)]
pub is_brand_goods: Option<bool>,
#[serde(default)]
pub desc_txt: Option<String>,
#[serde(default)]
pub lgst_txt: Option<String>,
#[serde(default)]
pub serv_txt: Option<String>,
#[serde(default)]
pub activity_tags: Option<Vec<i32>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderResponse {
#[serde(default, rename = "order_list_get_response")]
pub response: Option<PddOrderListResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderListResult {
#[serde(default)]
pub total_count: Option<i64>,
#[serde(default)]
pub order_list: Option<Vec<PddOrderInfo>>,
#[serde(default)]
pub request_id: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderInfo {
#[serde(default)]
pub order_sn: Option<String>,
#[serde(default)]
pub goods_id: Option<i64>,
#[serde(default)]
pub goods_name: Option<String>,
#[serde(default)]
pub goods_thumbnail_url: Option<String>,
#[serde(default)]
pub goods_quantity: Option<i32>,
#[serde(default)]
pub goods_price: Option<i64>,
#[serde(default)]
pub order_amount: Option<i64>,
#[serde(default)]
pub promotion_amount: Option<i64>,
#[serde(default)]
pub promotion_rate: Option<i64>,
#[serde(default)]
pub order_status: Option<i32>,
#[serde(default)]
pub order_status_desc: Option<String>,
#[serde(default)]
pub order_create_time: Option<i64>,
#[serde(default)]
pub order_pay_time: Option<i64>,
#[serde(default)]
pub order_group_success_time: Option<i64>,
#[serde(default)]
pub order_receive_time: Option<i64>,
#[serde(default)]
pub order_settle_time: Option<i64>,
#[serde(default)]
pub order_modify_at: Option<i64>,
#[serde(default)]
pub custom_parameters: Option<String>,
#[serde(default)]
pub p_id: Option<String>,
#[serde(default)]
pub type_field: Option<i32>,
#[serde(default)]
pub order_type: Option<i32>,
#[serde(default)]
pub mall_id: Option<i64>,
#[serde(default)]
pub mall_name: Option<String>,
#[serde(default)]
pub cat_ids: Option<Vec<i64>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeResponse {
#[serde(default, rename = "rp_promotion_url_generate_response")]
pub response: Option<PddAuthorizeResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeResult {
#[serde(default)]
pub url_list: Option<Vec<PddAuthorizeUrl>>,
#[serde(default)]
pub request_id: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeUrl {
#[serde(default)]
pub mobile_url: Option<String>,
#[serde(default)]
pub url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeQueryResponse {
#[serde(default, rename = "authority_query_response")]
pub response: Option<PddAuthorizeQueryResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeQueryResult {
#[serde(default)]
pub bind: Option<i32>,
#[serde(default)]
pub request_id: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pdd_convert_response_deserialize() {
let json = r#"{
"goods_zs_unit_generate_response": {
"multi_group_mobile_short_url": "https://p.pinduoduo.com/2sB0eGpK",
"mobile_url": "https://mobile.yangkeduo.com/duo_coupon_landing.html",
"short_url": "https://p.pinduoduo.com/bOL0pBPH",
"request_id": "16942627387113959"
}
}"#;
let response: PddConvertResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert_eq!(
result.multi_group_mobile_short_url,
Some("https://p.pinduoduo.com/2sB0eGpK".to_string())
);
assert_eq!(
result.short_url,
Some("https://p.pinduoduo.com/bOL0pBPH".to_string())
);
}
#[test]
fn test_pdd_goods_detail_simple_response_deserialize() {
let json = r#"{
"goods_basic_detail_response": {
"goods_list": [{
"goods_name": "测试商品",
"goods_pic": "https://img.pddpic.com/test.jpeg",
"min_normal_price": 1900,
"goods_id": 453581732819,
"min_group_price": 990
}],
"request_id": "16942480364163726"
}
}"#;
let response: PddGoodsDetailSimpleResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert!(result.goods_list.is_some());
let goods = result.goods_list.unwrap();
assert_eq!(goods.len(), 1);
assert_eq!(goods[0].goods_name, Some("测试商品".to_string()));
assert_eq!(goods[0].goods_id, Some(453581732819));
}
#[test]
fn test_pdd_order_response_deserialize() {
let json = r#"{
"order_list_get_response": {
"total_count": 1,
"order_list": [{
"order_sn": "123456789",
"goods_id": 453581732819,
"goods_name": "测试商品",
"order_status": 2,
"order_amount": 9900,
"promotion_amount": 990
}],
"request_id": "16942626445817516"
}
}"#;
let response: PddOrderResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert_eq!(result.total_count, Some(1));
assert!(result.order_list.is_some());
let orders = result.order_list.unwrap();
assert_eq!(orders.len(), 1);
assert_eq!(orders[0].order_sn, Some("123456789".to_string()));
assert_eq!(orders[0].order_status, Some(2));
}
#[test]
fn test_pdd_authorize_response_deserialize() {
let json = r#"{
"rp_promotion_url_generate_response": {
"url_list": [{
"mobile_url": "https://mobile.yangkeduo.com/duo_coupon_landing.html_",
"url": "https://mobile.yangkeduo.com/duo_coupon_landing.html"
}],
"request_id": "16942480613190789"
}
}"#;
let response: PddAuthorizeResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert!(result.url_list.is_some());
let urls = result.url_list.unwrap();
assert_eq!(urls.len(), 1);
assert!(urls[0].mobile_url.is_some());
}
#[test]
fn test_pdd_authorize_query_response_deserialize() {
let json = r#"{
"authority_query_response": {
"bind": 1,
"request_id": "16942467231374196"
}
}"#;
let response: PddAuthorizeQueryResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert_eq!(result.bind, Some(1));
}
#[test]
fn test_response_with_missing_fields() {
let json = r#"{"order_list_get_response": {"total_count": 0}}"#;
let response: PddOrderResponse = serde_json::from_str(json).unwrap();
assert!(response.response.is_some());
let result = response.response.unwrap();
assert_eq!(result.total_count, Some(0));
assert!(result.order_list.is_none());
}
}