Crate preferences [] [src]

Read and write user-specific application data

This crate allows Rust developers to store and retrieve user-local preferences and other application data in a flexible and platform-appropriate way.

Though it was originally inspired by Java's convenient Preferences API, this crate is more flexible; any type that implements Serialize and Deserialize (from the wonderful serde) can be stored and retrieved as user data!

Usage

For convenience, the type PreferencesMap<T> is provided. (It's actually just a std::collections::HashMap<String, T>, where T defaults to String). This mirrors the Java API, which models user data as an opaque key-value store. As long as the map is instantiated over a type T which is serializable and deserializable, PreferencesTrait will be implemented for your map instance. This will allow you to seamlessly save and load user data with the save(..) and load(..) methods on PreferencesTrait.

Basic example

extern crate preferences;
use preferences::{PreferencesMap, PreferencesTrait};
 
fn main() {
 
    // Create a new preferences key-value map
    // (Under the hood: HashMap<String, String>)
    let mut faves: PreferencesMap<String> = PreferencesMap::new();
 
    // Edit the preferences (std::collections::HashMap)
    faves.insert("color".into(), "blue".into());
    faves.insert("programming language".into(), "Rust".into());
 
    // Store the user's preferences
    let prefs_key = "preferences-rs/examples/faves";
    faves.save(prefs_key);
 
    // ... Then do some stuff ...
 
    // Retrieve the user's preferences
    let mut loaded_faves = PreferencesMap::new();
    let load_result = loaded_faves.load(prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(loaded_faves, faves);
 
}

Using custom data types

#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate preferences;
use preferences::{PreferencesMap, PreferencesTrait};
 
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct PlayerData {
    level: u32,
    health: f32,
}
 
fn main() {
 
    let player = PlayerData{level: 2, health: 0.75};
 
    let prefs_key = "preferences-rs/examples/player";
    player.save(prefs_key);

    let mut loaded_player = PlayerData{level: 0, health: 0.0};
    let load_result = loaded_player.load(prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(loaded_player, player);
 
}

Using custom data types with PreferencesMap

#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate preferences;
use preferences::{PreferencesMap, PreferencesTrait};
 
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Point(f32, f32);
 
fn main() {
 
    let mut places = PreferencesMap::new();
    places.insert("treasure".into(), Point(1.0, 1.0));
    places.insert("home".into(), Point(-1.0, 6.6));
 
    let prefs_key = "preferences-rs/examples/places";
    places.save(prefs_key);

    let mut loaded_places = PreferencesMap::new();
    let load_result = loaded_places.load(prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(loaded_places, places);
 
}

Using custom data types with serializable containers

#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate preferences;
use preferences::{PreferencesMap, PreferencesTrait};
 
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Point(usize, usize);
 
fn main() {
 
    let square = vec![
        Point(0,0),
        Point(1,0),
        Point(1,1),
        Point(0,1),
    ];
 
    let prefs_key = "preferences-rs/examples/square";
    square.save(prefs_key);

    let mut loaded_square: Vec<Point> = Vec::new();
    let load_result = loaded_square.load(prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(loaded_square, square);
 
}

Under the hood

Data is written to flat files under the active user's home directory in a location specific to the operating system.

  • Mac OS X: ~/Library/Preferences
  • Other Unix/Linux: ~/.config
  • Windows: %USERPROFILE%\AppData\Roaming (a.k.a. %APPDATA%)

The data is stored in JSON format. This has several advantages:

  • Human-readable and self-describing
  • More compact than e.g. XML
  • Not reliant on a consistent memory layout like e.g. binary

You could, of course, implement PreferencesTrait yourself and store your user data in whatever location and format that you wanted. But that would defeat the purpose of this library. 😊

Enums

PreferencesError

Error type representing the errors that can occur when saving or loading user data.

Traits

PreferencesTrait

Trait for types that can be saved & loaded as user data.

Type Definitions

PreferencesMap

Generic key-value store for user data.