1use crate::cookie::Cookie;
2use crate::fingerprint::BrowserFingerprint;
3use crate::proxy::ProxyConfig;
4use std::collections::HashMap;
5
6#[derive(Debug, Clone)]
11pub struct SolveRequest {
12 pub url: String,
13 pub method: SolveMethod,
14 pub headers: Option<HashMap<String, String>>,
15 pub cookies: Option<Vec<Cookie>>,
16 pub max_timeout_ms: Option<u64>,
17 pub session_id: Option<String>,
18 pub proxy: Option<ProxyConfig>,
19 pub bypass_cache: bool,
21 pub fingerprint: Option<BrowserFingerprint>,
23}
24
25#[derive(Debug, Clone)]
26pub enum SolveMethod {
27 Get,
28 Post { body: PostBody },
29}
30
31#[derive(Debug, Clone)]
32pub enum PostBody {
33 Form(HashMap<String, String>),
35 Json(serde_json::Value),
37 Raw {
39 content_type: String,
40 body: Vec<u8>,
41 },
42}
43
44impl SolveRequest {
45 pub fn get(url: impl Into<String>) -> Self {
46 Self {
47 url: url.into(),
48 method: SolveMethod::Get,
49 headers: None,
50 cookies: None,
51 max_timeout_ms: None,
52 session_id: None,
53 proxy: None,
54 bypass_cache: false,
55 fingerprint: None,
56 }
57 }
58
59 pub fn post(url: impl Into<String>) -> Self {
60 Self {
61 url: url.into(),
62 method: SolveMethod::Post {
63 body: PostBody::Form(HashMap::new()),
64 },
65 headers: None,
66 cookies: None,
67 max_timeout_ms: None,
68 session_id: None,
69 proxy: None,
70 bypass_cache: false,
71 fingerprint: None,
72 }
73 }
74
75 pub fn form<K, V, I>(mut self, fields: I) -> Self
77 where
78 K: Into<String>,
79 V: Into<String>,
80 I: IntoIterator<Item = (K, V)>,
81 {
82 let map = fields.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
83 self.method = SolveMethod::Post {
84 body: PostBody::Form(map),
85 };
86 self
87 }
88
89 pub fn json(mut self, value: serde_json::Value) -> Self {
91 self.method = SolveMethod::Post {
92 body: PostBody::Json(value),
93 };
94 self
95 }
96
97 pub fn raw_body(mut self, content_type: impl Into<String>, body: Vec<u8>) -> Self {
99 self.method = SolveMethod::Post {
100 body: PostBody::Raw {
101 content_type: content_type.into(),
102 body,
103 },
104 };
105 self
106 }
107
108 pub fn with_headers(mut self, headers: HashMap<String, String>) -> Self {
109 self.headers = Some(headers);
110 self
111 }
112
113 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
114 self.headers
115 .get_or_insert_with(HashMap::new)
116 .insert(name.into(), value.into());
117 self
118 }
119
120 pub fn with_cookies(mut self, cookies: Vec<Cookie>) -> Self {
121 self.cookies = Some(cookies);
122 self
123 }
124
125 pub fn with_cookie(mut self, cookie: Cookie) -> Self {
126 self.cookies.get_or_insert_with(Vec::new).push(cookie);
127 self
128 }
129
130 pub fn with_timeout_ms(mut self, ms: u64) -> Self {
131 self.max_timeout_ms = Some(ms);
132 self
133 }
134
135 pub fn with_session(mut self, session_id: impl Into<String>) -> Self {
136 self.session_id = Some(session_id.into());
137 self
138 }
139
140 pub fn with_proxy(mut self, proxy: ProxyConfig) -> Self {
141 self.proxy = Some(proxy);
142 self
143 }
144
145 pub fn bypass_cache(mut self) -> Self {
146 self.bypass_cache = true;
147 self
148 }
149
150 pub fn with_fingerprint(mut self, fingerprint: BrowserFingerprint) -> Self {
151 self.fingerprint = Some(fingerprint);
152 self
153 }
154}