1mod device;
2#[cfg(feature = "emulation-rand")]
3mod rand;
4
5use device::{chrome::*, firefox::*, okhttp::*, opera::*, safari::*};
6#[cfg(feature = "emulation-serde")]
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "emulation-rand")]
9use strum_macros::VariantArray;
10use typed_builder::TypedBuilder;
11use wreq::{EmulationProvider, EmulationProviderFactory};
12
13macro_rules! define_emulation_enum {
14 ($(#[$meta:meta])* $name:ident, $default_variant:ident, $($variant:ident => $rename:expr),*) => {
15 $(#[$meta])*
16 #[non_exhaustive]
17 #[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
18 #[cfg_attr(feature = "emulation-rand", derive(VariantArray))]
19 #[cfg_attr(feature = "emulation-serde", derive(Deserialize, Serialize))]
20 pub enum $name {
21 $(
22 #[cfg_attr(feature = "emulation-serde", serde(rename = $rename))]
23 $variant,
24 )*
25 }
26
27 impl Default for $name {
28 fn default() -> Self {
29 $name::$default_variant
30 }
31 }
32 };
33}
34
35define_emulation_enum!(
36 Emulation, Chrome133,
64 Chrome100 => "chrome_100",
65 Chrome101 => "chrome_101",
66 Chrome104 => "chrome_104",
67 Chrome105 => "chrome_105",
68 Chrome106 => "chrome_106",
69 Chrome107 => "chrome_107",
70 Chrome108 => "chrome_108",
71 Chrome109 => "chrome_109",
72 Chrome110 => "chrome_110",
73 Chrome114 => "chrome_114",
74 Chrome116 => "chrome_116",
75 Chrome117 => "chrome_117",
76 Chrome118 => "chrome_118",
77 Chrome119 => "chrome_119",
78 Chrome120 => "chrome_120",
79 Chrome123 => "chrome_123",
80 Chrome124 => "chrome_124",
81 Chrome126 => "chrome_126",
82 Chrome127 => "chrome_127",
83 Chrome128 => "chrome_128",
84 Chrome129 => "chrome_129",
85 Chrome130 => "chrome_130",
86 Chrome131 => "chrome_131",
87 Chrome132 => "chrome_132",
88 Chrome133 => "chrome_133",
89 Chrome134 => "chrome_134",
90 Chrome135 => "chrome_135",
91 Chrome136 => "chrome_136",
92 Chrome137 => "chrome_137",
93
94 SafariIos17_2 => "safari_ios_17.2",
95 SafariIos17_4_1 => "safari_ios_17.4.1",
96 SafariIos16_5 => "safari_ios_16.5",
97 Safari15_3 => "safari_15.3",
98 Safari15_5 => "safari_15.5",
99 Safari15_6_1 => "safari_15.6.1",
100 Safari16 => "safari_16",
101 Safari16_5 => "safari_16.5",
102 Safari17_0 => "safari_17.0",
103 Safari17_2_1 => "safari_17.2.1",
104 Safari17_4_1 => "safari_17.4.1",
105 Safari17_5 => "safari_17.5",
106 Safari18 => "safari_18",
107 SafariIPad18 => "safari_ipad_18",
108 Safari18_2 => "safari_18.2",
109 SafariIos18_1_1 => "safari_ios_18.1.1",
110 Safari18_3 => "safari_18.3",
111 Safari18_3_1 => "safari_18.3.1",
112 Safari18_5 => "safari_18.5",
113
114 OkHttp3_9 => "okhttp_3.9",
115 OkHttp3_11 => "okhttp_3.11",
116 OkHttp3_13 => "okhttp_3.13",
117 OkHttp3_14 => "okhttp_3.14",
118 OkHttp4_9 => "okhttp_4.9",
119 OkHttp4_10 => "okhttp_4.10",
120 OkHttp4_12 => "okhttp_4.12",
121 OkHttp5 => "okhttp_5",
122
123 Edge101 => "edge_101",
124 Edge122 => "edge_122",
125 Edge127 => "edge_127",
126 Edge131 => "edge_131",
127 Edge134 => "edge_134",
128
129 Firefox109 => "firefox_109",
130 Firefox117 => "firefox_117",
131 Firefox128 => "firefox_128",
132 Firefox133 => "firefox_133",
133 Firefox135 => "firefox_135",
134 FirefoxPrivate135 => "firefox_private_135",
135 FirefoxAndroid135 => "firefox_android_135",
136 Firefox136 => "firefox_136",
137 FirefoxPrivate136 => "firefox_private_136",
138 Firefox139 => "firefox_139",
139
140 Opera116 => "opera_116",
141 Opera117 => "opera_117",
142 Opera118 => "opera_118",
143 Opera119 => "opera_119"
144);
145
146impl EmulationProviderFactory for Emulation {
148 fn emulation(self) -> EmulationProvider {
149 EmulationOption::builder()
150 .emulation(self)
151 .build()
152 .emulation()
153 }
154}
155
156define_emulation_enum!(
157 EmulationOS, MacOS,
183 Windows => "windows",
184 MacOS => "macos",
185 Linux => "linux",
186 Android => "android",
187 IOS => "ios"
188);
189
190impl EmulationOS {
192 #[inline]
193 const fn platform(&self) -> &'static str {
194 match self {
195 EmulationOS::MacOS => "\"macOS\"",
196 EmulationOS::Linux => "\"Linux\"",
197 EmulationOS::Windows => "\"Windows\"",
198 EmulationOS::Android => "\"Android\"",
199 EmulationOS::IOS => "\"iOS\"",
200 }
201 }
202
203 #[inline]
204 const fn is_mobile(&self) -> bool {
205 matches!(self, EmulationOS::Android | EmulationOS::IOS)
206 }
207}
208
209#[derive(Default, Clone, TypedBuilder)]
241pub struct EmulationOption {
242 #[builder(default)]
244 emulation: Emulation,
245
246 #[builder(default)]
248 emulation_os: EmulationOS,
249
250 #[builder(default = false)]
252 skip_http2: bool,
253
254 #[builder(default = false)]
256 skip_headers: bool,
257}
258
259macro_rules! emulation_match {
261 ($ver:expr, $opt:expr, $($variant:pat => $path:expr),+) => {
262 match $ver {
263 $(
264 $variant => $path($opt),
265 )+
266 }
267 }
268}
269
270impl EmulationProviderFactory for EmulationOption {
271 fn emulation(self) -> EmulationProvider {
272 emulation_match!(
273 self.emulation,
274 self,
275
276 Emulation::Chrome100 => v100::emulation,
277 Emulation::Chrome101 => v101::emulation,
278 Emulation::Chrome104 => v104::emulation,
279 Emulation::Chrome105 => v105::emulation,
280 Emulation::Chrome106 => v106::emulation,
281 Emulation::Chrome107 => v107::emulation,
282 Emulation::Chrome108 => v108::emulation,
283 Emulation::Chrome109 => v109::emulation,
284 Emulation::Chrome110 => v110::emulation,
285 Emulation::Chrome114 => v114::emulation,
286 Emulation::Chrome116 => v116::emulation,
287 Emulation::Chrome117 => v117::emulation,
288 Emulation::Chrome118 => v118::emulation,
289 Emulation::Chrome119 => v119::emulation,
290 Emulation::Chrome120 => v120::emulation,
291 Emulation::Chrome123 => v123::emulation,
292 Emulation::Chrome124 => v124::emulation,
293 Emulation::Chrome126 => v126::emulation,
294 Emulation::Chrome127 => v127::emulation,
295 Emulation::Chrome128 => v128::emulation,
296 Emulation::Chrome129 => v129::emulation,
297 Emulation::Chrome130 => v130::emulation,
298 Emulation::Chrome131 => v131::emulation,
299 Emulation::Chrome132 => v132::emulation,
300 Emulation::Chrome133 => v133::emulation,
301 Emulation::Chrome134 => v134::emulation,
302 Emulation::Chrome135 => v135::emulation,
303 Emulation::Chrome136 => v136::emulation,
304 Emulation::Chrome137 => v137::emulation,
305
306 Emulation::SafariIos17_2 => safari_ios_17_2::emulation,
307 Emulation::SafariIos17_4_1 => safari_ios_17_4_1::emulation,
308 Emulation::SafariIos16_5 => safari_ios_16_5::emulation,
309 Emulation::Safari15_3 => safari15_3::emulation,
310 Emulation::Safari15_5 => safari15_5::emulation,
311 Emulation::Safari15_6_1 => safari15_6_1::emulation,
312 Emulation::Safari16 => safari16::emulation,
313 Emulation::Safari16_5 => safari16_5::emulation,
314 Emulation::Safari17_0 => safari17_0::emulation,
315 Emulation::Safari17_2_1 => safari17_2_1::emulation,
316 Emulation::Safari17_4_1 => safari17_4_1::emulation,
317 Emulation::Safari17_5 => safari17_5::emulation,
318 Emulation::Safari18 => safari18::emulation,
319 Emulation::SafariIPad18 => safari_ipad_18::emulation,
320 Emulation::Safari18_2 => safari18_2::emulation,
321 Emulation::SafariIos18_1_1 => safari_ios_18_1_1::emulation,
322 Emulation::Safari18_3 => safari18_3::emulation,
323 Emulation::Safari18_3_1 => safari18_3_1::emulation,
324 Emulation::Safari18_5 => safari18_5::emulation,
325
326 Emulation::OkHttp3_9 => okhttp3_9::emulation,
327 Emulation::OkHttp3_11 => okhttp3_11::emulation,
328 Emulation::OkHttp3_13 => okhttp3_13::emulation,
329 Emulation::OkHttp3_14 => okhttp3_14::emulation,
330 Emulation::OkHttp4_9 => okhttp4_9::emulation,
331 Emulation::OkHttp4_10 => okhttp4_10::emulation,
332 Emulation::OkHttp4_12 => okhttp4_12::emulation,
333 Emulation::OkHttp5 => okhttp5::emulation,
334
335 Emulation::Edge101 => edge101::emulation,
336 Emulation::Edge122 => edge122::emulation,
337 Emulation::Edge127 => edge127::emulation,
338 Emulation::Edge131 => edge131::emulation,
339 Emulation::Edge134 => edge134::emulation,
340
341 Emulation::Firefox109 => ff109::emulation,
342 Emulation::Firefox117 => ff117::emulation,
343 Emulation::Firefox128 => ff128::emulation,
344 Emulation::Firefox133 => ff133::emulation,
345 Emulation::Firefox135 => ff135::emulation,
346 Emulation::FirefoxPrivate135 => ff_private_135::emulation,
347 Emulation::FirefoxAndroid135 => ff_android_135::emulation,
348 Emulation::Firefox136 => ff136::emulation,
349 Emulation::FirefoxPrivate136 => ff_private_136::emulation,
350 Emulation::Firefox139 => ff139::emulation,
351
352 Emulation::Opera116 => opera116::emulation,
353 Emulation::Opera117 => opera117::emulation,
354 Emulation::Opera118 => opera118::emulation,
355 Emulation::Opera119 => opera119::emulation
356 )
357 }
358}