use std::collections::{HashMap, HashSet}; use crate::chromium::{InstalledBrowserRetriever, PLATFORM_SUPPORTED_BROWSERS}; /// Mechanisms that load data into the importer pub struct NativeImporterMetadata { /// Identifies the importer pub id: String, /// Describes the strategies used to obtain imported data pub loaders: Vec<&'static str>, /// Identifies the instructions for the importer pub instructions: &'static str, } /// Returns a map of supported importers based on the current platform. /// /// Only browsers listed in PLATFORM_SUPPORTED_BROWSERS will have the "chromium" loader. /// All importers will have the "file" loader. pub fn get_supported_importers( mas_build: bool, ) -> HashMap { let mut map = HashMap::new(); // Check for installed browsers let installed_browsers = T::get_installed_browsers(mas_build).unwrap_or_default(); const IMPORTERS: &[(&str, &str)] = &[ ("chromecsv", "Chrome"), ("chromiumcsv", "Chromium"), ("bravecsv", "Brave"), ("operacsv", "Opera"), ("vivaldicsv", "Vivaldi"), ("edgecsv", "Microsoft Edge"), ]; let supported: HashSet<&'static str> = PLATFORM_SUPPORTED_BROWSERS.iter().map(|b| b.name).collect(); for (id, browser_name) in IMPORTERS { let mut loaders: Vec<&'static str> = vec!["file"]; if supported.contains(browser_name) { loaders.push("chromium"); } if installed_browsers.contains(&browser_name.to_string()) { map.insert( id.to_string(), NativeImporterMetadata { id: id.to_string(), loaders, instructions: "chromium", }, ); } } map } // Tests are cfg-gated based upon OS, and must be compiled/run on each OS for full coverage #[cfg(test)] mod tests { use std::collections::HashSet; use super::*; use crate::chromium::{InstalledBrowserRetriever, SUPPORTED_BROWSER_MAP}; pub struct MockInstalledBrowserRetriever {} impl InstalledBrowserRetriever for MockInstalledBrowserRetriever { fn get_installed_browsers(_mas_build: bool) -> Result, anyhow::Error> { Ok(SUPPORTED_BROWSER_MAP .keys() .map(|browser| browser.to_string()) .collect()) } } fn map_keys(map: &HashMap) -> HashSet { map.keys().cloned().collect() } fn get_loaders( map: &HashMap, id: &str, ) -> HashSet<&'static str> { map.get(id) .map(|m| m.loaders.iter().copied().collect::>()) .unwrap_or_default() } #[cfg(target_os = "macos")] #[test] fn macos_returns_all_known_importers() { let map = get_supported_importers::(false); let expected: HashSet = HashSet::from([ "chromecsv".to_string(), "chromiumcsv".to_string(), "bravecsv".to_string(), "operacsv".to_string(), "vivaldicsv".to_string(), "edgecsv".to_string(), ]); assert_eq!(map.len(), expected.len()); assert_eq!(map_keys(&map), expected); for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); assert!(meta.loaders.contains(&"file")); } } #[cfg(target_os = "macos")] #[test] fn macos_specific_loaders_match_const_array() { let map = get_supported_importers::(false); let ids = [ "chromecsv", "chromiumcsv", "bravecsv", "operacsv", "vivaldicsv", "edgecsv", ]; for id in ids { let loaders = get_loaders(&map, id); assert!(loaders.contains("file")); assert!(loaders.contains("chromium"), "missing chromium for {id}"); } } #[cfg(target_os = "linux")] #[test] fn returns_all_known_importers() { let map = get_supported_importers::(false); let expected: HashSet = HashSet::from([ "chromecsv".to_string(), "chromiumcsv".to_string(), "bravecsv".to_string(), "operacsv".to_string(), ]); assert_eq!(map.len(), expected.len()); assert_eq!(map_keys(&map), expected); for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); assert!(meta.loaders.contains(&"file")); } } #[cfg(target_os = "linux")] #[test] fn linux_specific_loaders_match_const_array() { let map = get_supported_importers::(false); let ids = ["chromecsv", "chromiumcsv", "bravecsv", "operacsv"]; for id in ids { let loaders = get_loaders(&map, id); assert!(loaders.contains("file")); assert!(loaders.contains("chromium"), "missing chromium for {id}"); } } #[cfg(target_os = "windows")] #[test] fn returns_all_known_importers() { let map = get_supported_importers::(false); let expected: HashSet = HashSet::from([ "bravecsv".to_string(), "chromecsv".to_string(), "chromiumcsv".to_string(), "edgecsv".to_string(), "operacsv".to_string(), "vivaldicsv".to_string(), ]); assert_eq!(map.len(), expected.len()); assert_eq!(map_keys(&map), expected); for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); assert!(meta.loaders.contains(&"file")); } } #[cfg(target_os = "windows")] #[test] fn windows_specific_loaders_match_const_array() { let map = get_supported_importers::(false); let ids = [ "bravecsv", "chromecsv", "chromiumcsv", "edgecsv", "operacsv", "vivaldicsv", ]; for id in ids { let loaders = get_loaders(&map, id); assert!(loaders.contains("file")); assert!(loaders.contains("chromium"), "missing chromium for {id}"); } } }