use crate::error::IdentityError;
use crate::identity::{Browser, Gpu, Identity, IdentityCountryGeo, NavigatorPlatform, Os, PlatformInfo, ScreenResolution};
fn win_platform(ver: &str) -> PlatformInfo {
PlatformInfo {
bitness: Some("64".into()),
architecture: Some("x86".into()),
navigator_platform: NavigatorPlatform::Win32,
version: ver.into(),
}
}
fn mac_platform(ver: &str) -> PlatformInfo {
PlatformInfo {
bitness: Some("64".into()),
architecture: Some("arm".into()),
navigator_platform: NavigatorPlatform::MacIntel,
version: ver.into(),
}
}
fn lin_platform(ver: &str) -> PlatformInfo {
PlatformInfo {
bitness: Some("64".into()),
architecture: Some("x86".into()),
navigator_platform: NavigatorPlatform::LinuxX86_64,
version: ver.into(),
}
}
fn screen(lw: u16, lh: u16, ow: u16, oh: u16, dpr: f32) -> ScreenResolution {
ScreenResolution {
logical_width: lw,
logical_height: lh,
original_width: ow,
original_height: oh,
density_pixel_ratio: dpr,
}
}
fn nvidia_gpu(model: &str) -> Gpu {
Gpu {
vendor: "NVIDIA Corporation".into(),
webgl_renderer: format!("ANGLE (NVIDIA {} Direct3D11 vs_5_0 ps_5_0)", model),
webgl_vendor: "Google Inc. (NVIDIA)".into(),
}
}
fn intel_gpu(model: &str) -> Gpu {
Gpu {
vendor: "Intel Inc.".into(),
webgl_renderer: format!("ANGLE (Intel, {} Direct3D11 vs_5_0 ps_5_0)", model),
webgl_vendor: "Google Inc. (Intel)".into(),
}
}
fn apple_gpu(model: &str) -> Gpu {
Gpu {
vendor: "Apple".into(),
webgl_renderer: model.into(),
webgl_vendor: "Apple".into(),
}
}
fn amd_gpu(model: &str) -> Gpu {
Gpu {
vendor: "Advanced Micro Devices, Inc.".into(),
webgl_renderer: format!("ANGLE (AMD, {} Direct3D11 vs_5_0 ps_5_0)", model),
webgl_vendor: "Google Inc. (AMD)".into(),
}
}
fn all() -> [Identity; 10] {
[
Identity {
id: Some(1),
device_model: None,
has_battery: false,
has_mouse: true,
has_touch: false,
os: Os::Windows,
os_version: "15.0.0".into(),
platform: win_platform("15.0.0"),
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 78],
screen: screen(1920, 1080, 1920, 1080, 1.0),
hardware_concurrency: 16,
memory: 16,
gpu: nvidia_gpu("GeForce RTX 3080"),
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(12),
proxy: None,
timezone: None
},
Identity {
id: Some(2),
device_model: None,
has_battery: false,
has_mouse: true,
has_touch: false,
os: Os::Windows,
os_version: "10.0.0".into(),
platform: win_platform("10.0.0"),
browser: Browser::Edge,
browser_version: vec![123, 0, 2420, 65],
screen: screen(1366, 768, 1366, 768, 1.0),
hardware_concurrency: 8,
memory: 8,
gpu: intel_gpu("Intel(R) UHD Graphics 630"),
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(5),
proxy: None,
timezone: None
},
Identity {
id: Some(3),
device_model: None,
has_battery: true,
has_mouse: true,
has_touch: false,
os: Os::Macintosh,
os_version: "13.4.1".into(),
platform: mac_platform("13.4.1"),
browser: Browser::Safari,
browser_version: vec![17, 0, 0, 0],
screen: screen(2560, 1600, 2560, 1600, 2.0),
hardware_concurrency: 10,
memory: 16,
gpu: apple_gpu("Apple M2"),
geo: IdentityCountryGeo::UK,
language: vec!["en-GB".into(), "en".into()],
history_count: Some(20),
proxy: None,
timezone: None
},
Identity {
id: Some(4),
device_model: None,
has_battery: true,
has_mouse: true,
has_touch: false,
os: Os::Macintosh,
os_version: "12.6.0".into(),
platform: mac_platform("12.6.0"),
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 82],
screen: screen(1440, 900, 2880, 1800, 2.0),
hardware_concurrency: 8,
memory: 8,
gpu: apple_gpu("Apple M1"),
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(7),
proxy: None,
timezone: None
},
Identity {
id: Some(5),
device_model: None,
has_battery: false,
has_mouse: true,
has_touch: false,
os: Os::Linux,
os_version: "22.04".into(),
platform: lin_platform("22.04"),
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 79],
screen: screen(1920, 1080, 1920, 1080, 1.0),
hardware_concurrency: 12,
memory: 16,
gpu: nvidia_gpu("GeForce GTX 1650"),
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(3),
proxy: None,
timezone: None
},
Identity {
id: Some(6),
device_model: Some("Pixel 7".into()),
has_battery: true,
has_mouse: false,
has_touch: true,
os: Os::Android,
os_version: "13".into(),
platform: PlatformInfo {
bitness: None,
architecture: None,
navigator_platform: NavigatorPlatform::LinuxArmV81,
version: "13".into(),
},
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 82],
screen: screen(412, 915, 1080, 2400, 2.625),
hardware_concurrency: 8,
memory: 8,
gpu: Gpu {
vendor: "Qualcomm".into(),
webgl_renderer: "Adreno (TM) 730".into(),
webgl_vendor: "Qualcomm".into(),
},
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(2),
proxy: None,
timezone: None
},
Identity {
id: Some(7),
device_model: Some("iPhone 15".into()),
has_battery: true,
has_mouse: false,
has_touch: true,
os: Os::Ios,
os_version: "17.0".into(),
platform: PlatformInfo {
bitness: None,
architecture: None,
navigator_platform: NavigatorPlatform::IPhone,
version: "17.0".into(),
},
browser: Browser::Safari,
browser_version: vec![17, 0, 0, 0],
screen: screen(393, 852, 1179, 2556, 3.0),
hardware_concurrency: 6,
memory: 6,
gpu: apple_gpu("Apple A16 GPU"),
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(4),
proxy: None,
timezone: None
},
Identity {
id: Some(8),
device_model: None,
has_battery: true,
has_mouse: true,
has_touch: true,
os: Os::Windows,
os_version: "11.0.0".into(),
platform: win_platform("11.0.0"),
browser: Browser::Chrome,
browser_version: vec![123, 0, 6312, 122],
screen: screen(1920, 1200, 1920, 1200, 1.0),
hardware_concurrency: 8,
memory: 16,
gpu: amd_gpu("AMD Radeon RX 6600"),
geo: IdentityCountryGeo::FR,
language: vec!["fr-FR".into(), "fr".into(), "en".into()],
history_count: Some(9),
proxy: None,
timezone: None
},
Identity {
id: Some(9),
device_model: None,
has_battery: true,
has_mouse: true,
has_touch: false,
os: Os::Macintosh,
os_version: "14.2.1".into(),
platform: mac_platform("14.2.1"),
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 91],
screen: screen(1512, 982, 3024, 1964, 2.0),
hardware_concurrency: 12,
memory: 36,
gpu: apple_gpu("Apple M3 Pro"),
geo: IdentityCountryGeo::DE,
language: vec!["de-DE".into(), "de".into(), "en".into()],
history_count: Some(15),
proxy: None,
timezone: None
},
Identity {
id: Some(10),
device_model: Some("SM-S911B".into()),
has_battery: true,
has_mouse: false,
has_touch: true,
os: Os::Android,
os_version: "14".into(),
platform: PlatformInfo {
bitness: None,
architecture: None,
navigator_platform: NavigatorPlatform::LinuxArmV81,
version: "14".into(),
},
browser: Browser::Chrome,
browser_version: vec![124, 0, 6367, 82],
screen: screen(360, 780, 1080, 2340, 3.0),
hardware_concurrency: 8,
memory: 8,
gpu: Gpu {
vendor: "Samsung".into(),
webgl_renderer: "Xclipse 920".into(),
webgl_vendor: "Samsung".into(),
},
geo: IdentityCountryGeo::US,
language: vec!["en-US".into(), "en".into()],
history_count: Some(6),
proxy: None,
timezone: None
},
]
}
pub fn presets() -> Vec<Identity> {
all().to_vec()
}
pub fn get_by_id(id: u64) -> Result<Identity, IdentityError> {
all()
.into_iter()
.find(|p| p.id == Some(id))
.ok_or(IdentityError::NotFound(id))
}
pub fn random() -> Identity {
let idx = entropy_index(all().len());
all().into_iter().nth(idx).expect("preset index in bounds")
}
fn entropy_index(len: usize) -> usize {
use std::time::{SystemTime, UNIX_EPOCH};
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.subsec_nanos())
.unwrap_or(42);
(nanos as usize) % len
}