Crate ffcv

Crate ffcv 

Source
Expand description

§ffcv - Firefox Configuration Viewer Library

This library provides functionality for parsing and querying Firefox preference files (prefs.js). It can parse Firefox’s custom JavaScript-like preference format, manage Firefox profiles, and filter preferences by glob patterns.

§Features

  • Parse Firefox prefs.js files with full JavaScript escape sequence support
  • Extract and merge Firefox’s built-in default preferences from omni.ja archives
  • Auto-discover Firefox installations across platforms (Linux, macOS, Windows)
  • Detect and manage Firefox profiles across platforms
  • Query preferences using glob patterns (e.g., "network.*", "browser.*.enabled")
  • Get human-readable explanations for documented preferences
  • Support for all four preference types: user, default, locked, and sticky
  • Track preference sources (built-in, global defaults, user-modified)

§Quick Start

§Parsing Preferences

use ffcv::{parse_prefs_js, PrefType, PrefValue};

let content = r#"
    user_pref("browser.startup.homepage", "https://example.com");
    pref("javascript.enabled", true);
    lock_pref("security.default_ssl_enabled", false);
"#;

let prefs = parse_prefs_js(content)?;
let homepage = prefs.iter()
    .find(|e| e.key == "browser.startup.homepage")
    .unwrap();
assert_eq!(homepage.value, PrefValue::String("https://example.com".to_string()));
assert_eq!(homepage.pref_type, PrefType::User);

For convenient value type checking, import the PrefValueExt trait:

use ffcv::{parse_prefs_js, PrefValue, PrefValueExt};

let content = r#"user_pref("javascript.enabled", true);"#;
let prefs = parse_prefs_js(content)?;
let entry = &prefs[0];

// Use convenience methods from PrefValueExt
if let Some(enabled) = entry.value.as_bool() {
    println!("JavaScript enabled: {}", enabled);
}

§Working with Profiles

use ffcv::{find_profile_path, parse_prefs_js};

// Find a specific Firefox profile
let profile_path = find_profile_path("default", None)?;
let prefs_path = profile_path.join("prefs.js");

// Read and parse preferences
let content = std::fs::read_to_string(&prefs_path)?;
let prefs = parse_prefs_js(&content)?;

§Listing All Profiles

use ffcv::list_profiles;

let profiles = list_profiles(None)?;
for profile in profiles {
    println!("Profile: {} ({})", profile.name, profile.path.display());
    if profile.is_default {
        println!("  (default profile)");
    }
}

§Querying Preferences

use ffcv::{parse_prefs_js, query_preferences};

let content = r#"
    user_pref("network.proxy.http", "proxy.example.com");
    user_pref("network.proxy.http_port", 8080);
    user_pref("browser.startup.homepage", "https://example.com");
"#;

let prefs = parse_prefs_js(content)?;
let network_prefs = query_preferences(&prefs, &["network.*"])?;

assert_eq!(network_prefs.len(), 2);
assert!(network_prefs.iter().any(|e| e.key == "network.proxy.http"));

§Firefox Installation Discovery

use ffcv::find_firefox_installation;

// Auto-detect Firefox installation on your system
match find_firefox_installation()? {
    Some(installation) => {
        println!("Firefox found at: {}", installation.path.display());
        println!("Version: {}", installation.version);
        println!("Has omni.ja: {}", installation.has_omni_ja);
    }
    None => println!("No Firefox installation found"),
}

§Merging All Preference Sources

use ffcv::{merge_all_preferences, find_profile_path, MergeConfig};

let profile_path = find_profile_path("default-release", None)?;

let config = MergeConfig {
    include_builtins: true,   // Include omni.ja defaults
    include_globals: true,    // Include greprefs.js
    include_user: true,       // Include user prefs.js
    continue_on_error: true,  // Don't fail if some sources are missing
};

let merged = merge_all_preferences(&profile_path, None, &config)?;

println!("Loaded {} preferences from {} sources",
    merged.entries.len(),
    merged.loaded_sources.len()
);

// Display warnings for any missing sources
for warning in &merged.warnings {
    eprintln!("Warning: {}", warning);
}

§Filtering User-Modified Preferences

use ffcv::{merge_all_preferences, find_profile_path, MergeConfig, PrefSource};

let profile_path = find_profile_path("default-release", None)?;
let config = MergeConfig::default();
let merged = merge_all_preferences(&profile_path, None, &config)?;

// Get only user-modified preferences (exclude built-ins)
let user_modified: Vec<_> = merged.entries
    .iter()
    .filter(|p| p.source == Some(PrefSource::User))
    .collect();

println!("You've modified {} preferences", user_modified.len());

§Preference Types

Firefox supports four preference types, indicated by the function name used:

§Error Handling

All functions return Result<T, Error>. The Error enum provides detailed error context for programmatic handling:

use ffcv::{parse_prefs_js, Error};

let invalid_content = "user_pref(invalid syntax";
match parse_prefs_js(invalid_content) {
    Ok(config) => println!("Parsed successfully"),
    Err(Error::Parser { line, column, message }) => {
        eprintln!("Parse error at {}:{}: {}", line, column, message);
    }
    Err(e) => eprintln!("Other error: {}", e),
}

§Platform Support

This library automatically detects Firefox profiles on:

  • Linux: ~/.mozilla/firefox/
  • macOS: ~/Library/Application Support/Firefox/
  • Windows: %APPDATA%\Mozilla\Firefox\Profiles\

§See Also

Structs§

ExtractConfig
Configuration for omni.ja extraction
FirefoxInstallation
Firefox installation information
MergeConfig
Configuration for preference merging
MergedPreferences
Merged preferences from multiple sources
OmniExtractor
omni.ja archive extractor
PrefEntry
Internal type for parser that always includes pref type
ProfileInfo
Public profile information for listing

Enums§

Error
Errors that can occur during Firefox preference parsing and operations
PrefSource
Firefox preference source
PrefType
Firefox preference types
PrefValue
Firefox preference value types

Constants§

DEFAULT_MAX_OMNI_SIZE
Default maximum omni.ja file size (100MB)

Traits§

PrefValueExt
Extension trait providing convenience methods for PrefValue

Functions§

find_all_firefox_installations
Find all Firefox installations on the system
find_firefox_installation
Find the first valid Firefox installation on the system
find_profile_path
Find the Firefox profile directory based on the profile name
get_effective_pref
Get the effective value for a preference key
get_firefox_version
Get the Firefox version from an installation directory
get_prefs_path
Get the path to prefs.js for a given profile
list_profiles
List all available Firefox profiles
merge_all_preferences
Merge preferences from multiple sources
parse_prefs_js
Parse the prefs.js file and extract all preferences
parse_prefs_js_file
Parse a prefs.js file directly from a file path
query_preferences
Query configuration preferences by glob patterns (OR logic)

Type Aliases§

Result
Result type alias for convenience