browser_info/
browser_detection.rs1use crate::{BrowserInfoError, BrowserType};
6use active_win_pos_rs::ActiveWindow;
7
8pub struct BrowserMetadata {
10 pub version: Option<String>,
11 pub tabs_count: Option<u32>,
12 pub is_incognito: bool,
13}
14
15pub fn classify_browser(window: &ActiveWindow) -> Result<BrowserType, BrowserInfoError> {
17 let app_name = window.app_name.to_lowercase();
18
19 let process_path = window.process_path.to_str().unwrap_or("").to_lowercase();
20
21 if app_name.contains("chrome") && !app_name.contains("edge") {
23 Ok(BrowserType::Chrome)
24 } else if app_name.contains("firefox") {
25 Ok(BrowserType::Firefox)
26 } else if app_name.contains("msedge") || app_name.contains("edge") {
27 Ok(BrowserType::Edge)
28 } else if app_name.contains("safari") {
29 Ok(BrowserType::Safari)
30 } else if app_name.contains("brave") {
31 Ok(BrowserType::Brave)
32 } else if app_name.contains("opera") {
33 Ok(BrowserType::Opera)
34 } else if app_name.contains("vivaldi") {
35 Ok(BrowserType::Vivaldi)
36 } else if is_browser_by_path(&process_path) {
37 detect_browser_from_path(&process_path)
39 } else {
40 Err(BrowserInfoError::NotABrowser)
41 }
42}
43
44pub fn get_browser_metadata(
46 window: &ActiveWindow,
47 browser_type: &BrowserType,
48) -> Result<BrowserMetadata, BrowserInfoError> {
49 Ok(BrowserMetadata {
50 version: get_browser_version(window, browser_type),
51 tabs_count: count_tabs(window, browser_type),
52 is_incognito: detect_incognito_mode(window, browser_type),
53 })
54}
55
56fn is_browser_by_path(path: &str) -> bool {
57 let browser_indicators = [
58 "chrome", "firefox", "edge", "safari", "brave", "opera", "vivaldi",
59 ];
60 browser_indicators
61 .iter()
62 .any(|&indicator| path.contains(indicator))
63}
64
65fn detect_browser_from_path(path: &str) -> Result<BrowserType, BrowserInfoError> {
66 if path.contains("chrome") {
67 Ok(BrowserType::Chrome)
68 } else if path.contains("firefox") {
69 Ok(BrowserType::Firefox)
70 } else if path.contains("edge") {
71 Ok(BrowserType::Edge)
72 } else {
73 Ok(BrowserType::Unknown("detected_from_path".to_string()))
74 }
75}
76
77fn get_browser_version(_window: &ActiveWindow, _browser_type: &BrowserType) -> Option<String> {
78 None
80}
81
82fn count_tabs(_window: &ActiveWindow, _browser_type: &BrowserType) -> Option<u32> {
83 None
85}
86
87fn detect_incognito_mode(window: &ActiveWindow, _browser_type: &BrowserType) -> bool {
88 let title = window.title.to_lowercase();
90 title.contains("incognito") || title.contains("private") || title.contains("inprivate")
91}