capmonstercloud_client/requests/
binance.rs1use serde::Serialize;
2
3use super::{require_non_empty, CaptchaRequest};
4use crate::error::Result;
5use crate::proxy::ProxyInfo;
6use crate::timeouts::GetResultTimeouts;
7
8#[derive(Debug, Clone, Serialize)]
12pub struct BinanceTaskRequest {
13 #[serde(rename = "websiteURL")]
15 pub website_url: String,
16 #[serde(rename = "websiteKey")]
19 pub website_key: String,
20 #[serde(rename = "validateId")]
23 pub validate_id: String,
24 #[serde(flatten, skip_serializing_if = "Option::is_none")]
25 pub proxy: Option<ProxyInfo>,
26 #[serde(rename = "userAgent", skip_serializing_if = "Option::is_none")]
28 pub user_agent: Option<String>,
29}
30
31impl BinanceTaskRequest {
32 pub fn new(
33 website_url: impl Into<String>,
34 website_key: impl Into<String>,
35 validate_id: impl Into<String>,
36 ) -> Self {
37 Self {
38 website_url: website_url.into(),
39 website_key: website_key.into(),
40 validate_id: validate_id.into(),
41 proxy: None,
42 user_agent: None,
43 }
44 }
45
46 pub fn with_proxy(mut self, proxy: ProxyInfo) -> Self {
47 self.proxy = Some(proxy);
48 self
49 }
50
51 pub fn with_user_agent(mut self, value: impl Into<String>) -> Self {
52 self.user_agent = Some(value.into());
53 self
54 }
55}
56
57impl CaptchaRequest for BinanceTaskRequest {
58 const TASK_TYPE: &'static str = "BinanceTask";
59
60 fn timeouts(&self) -> GetResultTimeouts {
61 GetResultTimeouts::secs(1.0, 0.0, 1.0, 20.0)
62 }
63
64 fn validate(&self) -> Result<()> {
65 require_non_empty("websiteURL", &self.website_url)?;
66 require_non_empty("websiteKey", &self.website_key)?;
67 require_non_empty("validateId", &self.validate_id)?;
68 Ok(())
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::proxy::ProxyType;
76 use serde_json::json;
77
78 #[test]
79 fn minimal_task() {
80 let task = BinanceTaskRequest::new("https://example.com", "login", "vid")
81 .to_task()
82 .unwrap();
83 assert_eq!(
84 task,
85 json!({"type": "BinanceTask", "websiteURL": "https://example.com",
86 "websiteKey": "login", "validateId": "vid"})
87 );
88 }
89
90 #[test]
91 fn full_task() {
92 let task = BinanceTaskRequest::new("https://example.com", "login", "vid")
93 .with_proxy(ProxyInfo::new(ProxyType::Http, "1.2.3.4", 8080).with_auth("u", "p"))
94 .with_user_agent("UA")
95 .to_task()
96 .unwrap();
97 assert_eq!(
98 task,
99 json!({"type": "BinanceTask", "websiteURL": "https://example.com",
100 "websiteKey": "login", "validateId": "vid", "userAgent": "UA",
101 "proxyType": "http", "proxyAddress": "1.2.3.4", "proxyPort": 8080,
102 "proxyLogin": "u", "proxyPassword": "p"})
103 );
104 }
105
106 #[test]
107 fn empty_required_strings_are_rejected() {
108 let err = BinanceTaskRequest::new("", "k", "v").to_task().unwrap_err();
109 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains("websiteURL")));
110 let err = BinanceTaskRequest::new("https://example.com", "", "v")
111 .to_task()
112 .unwrap_err();
113 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains("websiteKey")));
114 let err = BinanceTaskRequest::new("https://example.com", "k", "")
115 .to_task()
116 .unwrap_err();
117 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains("validateId")));
118 }
119}