viewpoint_core/devices/
mod.rs

1//! Device descriptors for device emulation.
2//!
3//! This module provides predefined device descriptors that match common devices
4//! like iPhones, iPads, Pixel phones, and desktop configurations.
5//!
6//! # Example
7//!
8//! ```no_run
9//! use viewpoint_core::{Browser, devices};
10//!
11//! # async fn example() -> Result<(), viewpoint_core::CoreError> {
12//! let browser = Browser::launch().headless(true).launch().await?;
13//!
14//! let context = browser.new_context_builder()
15//!     .device(devices::IPHONE_13)
16//!     .build()
17//!     .await?;
18//! # Ok(())
19//! # }
20//! ```
21
22mod android;
23mod desktop;
24mod ipad;
25mod iphone;
26
27pub use android::*;
28pub use desktop::*;
29pub use ipad::*;
30pub use iphone::*;
31
32use crate::context::ViewportSize;
33
34/// Browser type for device descriptors.
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
36pub enum BrowserType {
37    /// Chromium-based browser.
38    #[default]
39    Chromium,
40    /// Firefox browser.
41    Firefox,
42    /// `WebKit` browser.
43    Webkit,
44}
45
46/// A device descriptor containing all properties needed to emulate a device.
47///
48/// Device descriptors include viewport dimensions, user agent strings,
49/// device scale factor, and touch/mobile capabilities.
50#[derive(Debug, Clone)]
51pub struct DeviceDescriptor {
52    /// Human-readable device name.
53    pub name: &'static str,
54    /// User agent string for this device.
55    pub user_agent: &'static str,
56    /// Viewport dimensions.
57    pub viewport: ViewportSize,
58    /// Device pixel ratio (scale factor).
59    pub device_scale_factor: f64,
60    /// Whether the device is a mobile device.
61    pub is_mobile: bool,
62    /// Whether the device has touch capability.
63    pub has_touch: bool,
64    /// Default browser type for this device.
65    pub default_browser_type: BrowserType,
66}
67
68impl DeviceDescriptor {
69    /// Create a new device descriptor.
70    pub const fn new(
71        name: &'static str,
72        user_agent: &'static str,
73        viewport: ViewportSize,
74        device_scale_factor: f64,
75        is_mobile: bool,
76        has_touch: bool,
77        default_browser_type: BrowserType,
78    ) -> Self {
79        Self {
80            name,
81            user_agent,
82            viewport,
83            device_scale_factor,
84            is_mobile,
85            has_touch,
86            default_browser_type,
87        }
88    }
89}
90
91/// Get a list of all available device descriptors.
92pub fn all_devices() -> Vec<&'static DeviceDescriptor> {
93    vec![
94        // iPhones
95        &IPHONE_14_PRO_MAX,
96        &IPHONE_14_PRO,
97        &IPHONE_14,
98        &IPHONE_13_PRO_MAX,
99        &IPHONE_13_PRO,
100        &IPHONE_13,
101        &IPHONE_13_MINI,
102        &IPHONE_12_PRO_MAX,
103        &IPHONE_12_PRO,
104        &IPHONE_12,
105        &IPHONE_12_MINI,
106        &IPHONE_11_PRO_MAX,
107        &IPHONE_11_PRO,
108        &IPHONE_11,
109        &IPHONE_SE_3,
110        &IPHONE_SE,
111        &IPHONE_13_LANDSCAPE,
112        // iPads
113        &IPAD_PRO_12_9,
114        &IPAD_PRO_11,
115        &IPAD_AIR,
116        &IPAD,
117        &IPAD_MINI,
118        &IPAD_PRO_11_LANDSCAPE,
119        // Pixels
120        &PIXEL_7_PRO,
121        &PIXEL_7,
122        &PIXEL_6_PRO,
123        &PIXEL_6,
124        &PIXEL_5,
125        &PIXEL_4,
126        &PIXEL_7_LANDSCAPE,
127        // Samsung
128        &GALAXY_S23_ULTRA,
129        &GALAXY_S23,
130        &GALAXY_S21,
131        &GALAXY_TAB_S8,
132        // Desktop
133        &DESKTOP_CHROME,
134        &DESKTOP_CHROME_HIDPI,
135        &DESKTOP_SAFARI,
136        &DESKTOP_FIREFOX,
137        &DESKTOP_EDGE,
138    ]
139}
140
141/// Find a device descriptor by name (case-insensitive).
142pub fn find_device(name: &str) -> Option<&'static DeviceDescriptor> {
143    let name_lower = name.to_lowercase();
144    all_devices()
145        .into_iter()
146        .find(|d| d.name.to_lowercase() == name_lower)
147}
148
149#[cfg(test)]
150mod tests;