use serde::Serialize;
use super::enums::{TaobaoOrderQueryType, TaobaoOrderStatus, TaobaoSignUrlType};
#[derive(Debug, Clone, Serialize)]
pub struct ConvertByItemIdRequest {
pub sid: String,
pub pid: String,
pub num_iid: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub special_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signurl: Option<TaobaoSignUrlType>,
}
impl ConvertByItemIdRequest {
pub fn new(sid: impl Into<String>, pid: impl Into<String>, num_iid: impl Into<String>) -> Self {
Self {
sid: sid.into(),
pid: pid.into(),
num_iid: num_iid.into(),
relation_id: None,
special_id: None,
signurl: None,
}
}
pub fn relation_id(mut self, relation_id: impl Into<String>) -> Self {
self.relation_id = Some(relation_id.into());
self
}
pub fn special_id(mut self, special_id: impl Into<String>) -> Self {
self.special_id = Some(special_id.into());
self
}
pub fn signurl(mut self, signurl: TaobaoSignUrlType) -> Self {
self.signurl = Some(signurl);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ConvertByTklRequest {
pub sid: String,
pub pid: String,
pub tkl: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub union_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub position_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_parameters: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chan_tag: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub customer_id: Option<String>,
}
impl ConvertByTklRequest {
pub fn new(sid: impl Into<String>, pid: impl Into<String>, tkl: impl Into<String>) -> Self {
Self {
sid: sid.into(),
pid: pid.into(),
tkl: tkl.into(),
relation_id: None,
union_id: None,
position_id: None,
custom_parameters: None,
chan_tag: None,
customer_id: None,
}
}
pub fn relation_id(mut self, relation_id: impl Into<String>) -> Self {
self.relation_id = Some(relation_id.into());
self
}
pub fn union_id(mut self, union_id: impl Into<String>) -> Self {
self.union_id = Some(union_id.into());
self
}
pub fn position_id(mut self, position_id: impl Into<String>) -> Self {
self.position_id = Some(position_id.into());
self
}
pub fn custom_parameters(mut self, custom_parameters: impl Into<String>) -> Self {
self.custom_parameters = Some(custom_parameters.into());
self
}
pub fn chan_tag(mut self, chan_tag: impl Into<String>) -> Self {
self.chan_tag = Some(chan_tag.into());
self
}
pub fn customer_id(mut self, customer_id: impl Into<String>) -> Self {
self.customer_id = Some(customer_id.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct BatchConvertRequest {
pub sid: String,
pub pid: String,
pub num_iid: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation_ids: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signurl: Option<TaobaoSignUrlType>,
}
impl BatchConvertRequest {
pub fn new(sid: impl Into<String>, pid: impl Into<String>, num_iid: impl Into<String>) -> Self {
Self {
sid: sid.into(),
pid: pid.into(),
num_iid: num_iid.into(),
relation_ids: None,
signurl: None,
}
}
pub fn relation_ids(mut self, relation_ids: impl Into<String>) -> Self {
self.relation_ids = Some(relation_ids.into());
self
}
pub fn signurl(mut self, signurl: TaobaoSignUrlType) -> Self {
self.signurl = Some(signurl);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct QueryOrdersRequest {
pub sid: String,
pub start_time: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub query_type: Option<TaobaoOrderQueryType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tk_status: Option<TaobaoOrderStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_no: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_size: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub special_id: Option<String>,
}
impl QueryOrdersRequest {
pub fn new(sid: impl Into<String>, start_time: impl Into<String>) -> Self {
Self {
sid: sid.into(),
start_time: start_time.into(),
end_time: None,
query_type: None,
tk_status: None,
page_no: None,
page_size: None,
relation_id: None,
special_id: None,
}
}
pub fn end_time(mut self, end_time: impl Into<String>) -> Self {
self.end_time = Some(end_time.into());
self
}
pub fn query_type(mut self, query_type: TaobaoOrderQueryType) -> Self {
self.query_type = Some(query_type);
self
}
pub fn tk_status(mut self, tk_status: TaobaoOrderStatus) -> Self {
self.tk_status = Some(tk_status);
self
}
pub fn page_no(mut self, page_no: u32) -> Self {
self.page_no = Some(page_no);
self
}
pub fn page_size(mut self, page_size: u32) -> Self {
self.page_size = Some(page_size);
self
}
pub fn relation_id(mut self, relation_id: impl Into<String>) -> Self {
self.relation_id = Some(relation_id.into());
self
}
pub fn special_id(mut self, special_id: impl Into<String>) -> Self {
self.special_id = Some(special_id.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateTklRequest {
pub sid: String,
pub pid: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub num_iid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub logo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation_id: Option<String>,
}
impl CreateTklRequest {
pub fn new(sid: impl Into<String>, pid: impl Into<String>) -> Self {
Self {
sid: sid.into(),
pid: pid.into(),
num_iid: None,
url: None,
text: None,
logo: None,
relation_id: None,
}
}
pub fn num_iid(mut self, num_iid: impl Into<String>) -> Self {
self.num_iid = Some(num_iid.into());
self
}
pub fn url(mut self, url: impl Into<String>) -> Self {
self.url = Some(url.into());
self
}
pub fn text(mut self, text: impl Into<String>) -> Self {
self.text = Some(text.into());
self
}
pub fn logo(mut self, logo: impl Into<String>) -> Self {
self.logo = Some(logo.into());
self
}
pub fn relation_id(mut self, relation_id: impl Into<String>) -> Self {
self.relation_id = Some(relation_id.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ParseItemIdRequest {
pub content: String,
}
impl ParseItemIdRequest {
pub fn new(content: impl Into<String>) -> Self {
Self {
content: content.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct SearchGoodsRequest {
pub sid: String,
pub pid: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub q: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_size: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub youquan: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tj: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub haiwai: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub itemloc: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_tk_rate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_tk_rate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "type")]
pub filter_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cat: Option<String>,
}
impl SearchGoodsRequest {
pub fn new(sid: impl Into<String>, pid: impl Into<String>) -> Self {
Self {
sid: sid.into(),
pid: pid.into(),
q: None,
page: None,
page_size: None,
sort: None,
youquan: None,
tj: None,
haiwai: None,
itemloc: None,
start_tk_rate: None,
end_tk_rate: None,
start_price: None,
end_price: None,
filter_type: None,
cat: None,
}
}
pub fn keyword(mut self, keyword: impl Into<String>) -> Self {
self.q = Some(keyword.into());
self
}
pub fn page(mut self, page: u32) -> Self {
self.page = Some(page);
self
}
pub fn page_size(mut self, page_size: u32) -> Self {
self.page_size = Some(page_size);
self
}
pub fn sort(mut self, sort: impl Into<String>) -> Self {
self.sort = Some(sort.into());
self
}
pub fn with_coupon(mut self) -> Self {
self.youquan = Some("1".to_string());
self
}
pub fn tmall_only(mut self) -> Self {
self.tj = Some("tmall".to_string());
self
}
pub fn overseas_only(mut self) -> Self {
self.haiwai = Some("1".to_string());
self
}
pub fn location(mut self, location: impl Into<String>) -> Self {
self.itemloc = Some(location.into());
self
}
pub fn commission_rate_range(mut self, start: u32, end: u32) -> Self {
self.start_tk_rate = Some(start.to_string());
self.end_tk_rate = Some(end.to_string());
self
}
pub fn price_range(mut self, start: f64, end: f64) -> Self {
self.start_price = Some(start.to_string());
self.end_price = Some(end.to_string());
self
}
pub fn filter(mut self, level: u32) -> Self {
self.filter_type = Some(level.to_string());
self
}
pub fn category(mut self, cat: impl Into<String>) -> Self {
self.cat = Some(cat.into());
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_convert_by_item_id_request_serialize() {
let request = ConvertByItemIdRequest::new("sid123", "mm_123_456_789", "987654321");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["sid"], "sid123");
assert_eq!(json["pid"], "mm_123_456_789");
assert_eq!(json["num_iid"], "987654321");
assert!(json.get("relation_id").is_none());
}
#[test]
fn test_convert_by_item_id_request_with_options() {
let request = ConvertByItemIdRequest::new("sid123", "mm_123_456_789", "987654321")
.relation_id("rel123")
.signurl(TaobaoSignUrlType::WithFullDetail);
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["relation_id"], "rel123");
assert_eq!(json["signurl"], 5);
}
#[test]
fn test_convert_by_tkl_request_serialize() {
let request = ConvertByTklRequest::new("sid123", "mm_123_456_789", "淘口令内容");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["sid"], "sid123");
assert_eq!(json["pid"], "mm_123_456_789");
assert_eq!(json["tkl"], "淘口令内容");
}
#[test]
fn test_batch_convert_request_serialize() {
let request = BatchConvertRequest::new("sid123", "mm_123_456_789", "987654321")
.relation_ids("rel1,rel2,rel3");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["relation_ids"], "rel1,rel2,rel3");
}
#[test]
fn test_query_orders_request_serialize() {
let request = QueryOrdersRequest::new("sid123", "2024-01-01 00:00:00")
.end_time("2024-01-31 23:59:59")
.query_type(TaobaoOrderQueryType::CreateTime)
.page_no(1)
.page_size(20);
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["start_time"], "2024-01-01 00:00:00");
assert_eq!(json["end_time"], "2024-01-31 23:59:59");
assert_eq!(json["query_type"], 1);
assert_eq!(json["page_no"], 1);
assert_eq!(json["page_size"], 20);
}
#[test]
fn test_create_tkl_request_serialize() {
let request = CreateTklRequest::new("sid123", "mm_123_456_789")
.num_iid("987654321")
.text("推荐好物");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["num_iid"], "987654321");
assert_eq!(json["text"], "推荐好物");
}
#[test]
fn test_parse_item_id_request_serialize() {
let request = ParseItemIdRequest::new("https://item.taobao.com/item.htm?id=123456");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(
json["content"],
"https://item.taobao.com/item.htm?id=123456"
);
}
#[test]
fn test_optional_fields_not_serialized() {
let request = ConvertByItemIdRequest::new("sid", "pid", "num_iid");
let json_str = serde_json::to_string(&request).unwrap();
assert!(!json_str.contains("relation_id"));
assert!(!json_str.contains("special_id"));
assert!(!json_str.contains("signurl"));
}
}