use crate::error::{Error, Result};
use crate::types::PrefEntry;
use glob::Pattern;
pub fn query_preferences(preferences: &[PrefEntry], patterns: &[&str]) -> Result<Vec<PrefEntry>> {
let compiled_patterns: Vec<Pattern> = patterns
.iter()
.map(|p| {
Pattern::new(p).map_err(|e| {
Error::InvalidGlobPattern(format!("Invalid query pattern '{}': {}", p, e))
})
})
.collect::<Result<Vec<_>>>()?;
let queried: Vec<PrefEntry> = preferences
.iter()
.filter(|entry| {
compiled_patterns
.iter()
.any(|pattern| pattern.matches(&entry.key))
})
.cloned()
.collect();
Ok(queried)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::PrefSource;
use crate::types::{PrefType, PrefValue};
fn create_test_config() -> Vec<PrefEntry> {
vec![
PrefEntry {
key: "network.proxy.type".to_string(),
value: PrefValue::Integer(1),
pref_type: PrefType::User,
explanation: None,
source: Some(PrefSource::User),
source_file: Some("prefs.js".to_string()),
locked: None,
},
PrefEntry {
key: "network.cookie.cookieBehavior".to_string(),
value: PrefValue::Integer(0),
pref_type: PrefType::User,
explanation: None,
source: Some(PrefSource::User),
source_file: Some("prefs.js".to_string()),
locked: None,
},
PrefEntry {
key: "browser.startup.homepage".to_string(),
value: PrefValue::String("https://example.com".to_string()),
pref_type: PrefType::User,
explanation: None,
source: Some(PrefSource::User),
source_file: Some("prefs.js".to_string()),
locked: None,
},
PrefEntry {
key: "browser.search.region".to_string(),
value: PrefValue::String("US".to_string()),
pref_type: PrefType::User,
explanation: None,
source: Some(PrefSource::User),
source_file: Some("prefs.js".to_string()),
locked: None,
},
PrefEntry {
key: "javascript.enabled".to_string(),
value: PrefValue::Bool(true),
pref_type: PrefType::Default,
explanation: None,
source: Some(PrefSource::User),
source_file: Some("prefs.js".to_string()),
locked: None,
},
]
}
#[test]
fn test_query_single_pattern() {
let config = create_test_config();
let queried = query_preferences(&config, &["network.*"]).unwrap();
assert_eq!(queried.len(), 2);
assert!(queried.iter().any(|e| e.key == "network.proxy.type"));
assert!(queried
.iter()
.any(|e| e.key == "network.cookie.cookieBehavior"));
}
#[test]
fn test_query_multiple_patterns_or_logic() {
let config = create_test_config();
let queried = query_preferences(&config, &["network.*", "javascript.enabled"]).unwrap();
assert_eq!(queried.len(), 3);
assert!(queried.iter().any(|e| e.key == "network.proxy.type"));
assert!(queried
.iter()
.any(|e| e.key == "network.cookie.cookieBehavior"));
assert!(queried.iter().any(|e| e.key == "javascript.enabled"));
}
#[test]
fn test_query_no_matches() {
let config = create_test_config();
let queried = query_preferences(&config, &["nonexistent.*"]).unwrap();
assert_eq!(queried.len(), 0);
assert!(queried.is_empty());
}
#[test]
fn test_query_invalid_pattern() {
let config = create_test_config();
let result = query_preferences(&config, &["[invalid"]);
assert!(result.is_err());
}
#[test]
fn test_query_exact_match() {
let config = create_test_config();
let queried = query_preferences(&config, &["javascript.enabled"]).unwrap();
assert_eq!(queried.len(), 1);
assert!(queried.iter().any(|e| e.key == "javascript.enabled"));
}
}