Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
//! Prefs file parsing utilities.
/// Parse a single pref value (if any) from the prefs file contents.
///
/// This parser could be improved (e.g., it doesn't respect comments), but it is compatible with
/// prefs files generated by Firefox.
///
/// This finds the first string match for the regex `user_pref\("PREFSTRING"[ \t\n\r\f\v,]*(.*)[ \t\n\r\f\v]*\);`.
///
/// For example:
/// ```rust
/// let input = r#"user_pref("FOOBAR", "baz");"#;
/// let expected_output = Some(r#""baz""#);
/// assert_eq!(find_pref(input, "FOOBAR"), output);
/// ```
pub fn find_pref<'a>(prefs_content: &'a str, pref: &str) -> Option<&'a str> {
let mut search_content = prefs_content;
loop {
let (before, s) = search_content.split_once(&format!("\"{pref}\""))?;
if !before.trim().ends_with("user_pref(") {
search_content = s;
continue;
}
let s = s.trim_start_matches(|c: char| c.is_whitespace() || c == ',');
let (content, _) = s.split_once(");")?;
return Some(content.trim());
}
}
/// Find a single string pref (if any) from the prefs file contents.
pub fn find_string_pref<'a>(prefs_content: &'a str, pref: &str) -> Option<&'a str> {
find_pref(prefs_content, pref).and_then(|s| s.strip_prefix('"')?.strip_suffix('"'))
}
/// Find a single bool pref (if any) from the prefs file contents.
pub fn find_bool_pref(prefs_content: &str, pref: &str) -> Option<bool> {
find_pref(prefs_content, pref).and_then(|s| s.parse().ok())
}
// Doctests don't run for binaries, so make some unit tests instead.
#[cfg(test)]
mod test {
use super::*;
#[test]
fn find_pref_read_value() {
let input = r#"user_pref("FOOBAR", "baz");"#;
assert_eq!(find_pref(input, "FOOBAR"), Some(r#""baz""#));
}
#[test]
fn find_pref_continues_search() {
let input = r#"
user_pref("rawr", "FOOBAR");
user_pref("FOOBAR", "baz");
"#;
assert_eq!(find_pref(input, "FOOBAR"), Some(r#""baz""#));
}
#[test]
fn find_pref_missing() {
let input = r#"
user_pref("rawr", "FOOBAR");
user_pref("FOOBAR", "hello");
"#;
assert_eq!(find_pref(input, "hello"), None);
}
#[test]
fn test_find_string_pref() {
let input = r#"user_pref("FOOBAR", "baz");"#;
assert_eq!(find_string_pref(input, "FOOBAR"), Some("baz"));
}
#[test]
fn test_find_bool_pref() {
let input = r#"user_pref("FOOBAR", true);"#;
assert_eq!(find_bool_pref(input, "FOOBAR"), Some(true));
let input = r#"user_pref("FOOBAR", false);"#;
assert_eq!(find_bool_pref(input, "FOOBAR"), Some(false));
}
}