#data #user #read-write #persistent #persistent-storage #storage

preferences

读取和写入特定用户的应用数据(在稳定 Rust 中)

14 个版本 (3 个稳定版本)

2.0.0 2024年7月9日
1.1.0 2017年2月16日
0.7.3 2016年11月10日
0.5.0 2016年3月10日

配置 中排名第 141

Download history 124/week @ 2024-05-05 145/week @ 2024-05-12 131/week @ 2024-05-19 214/week @ 2024-05-26 250/week @ 2024-06-02 145/week @ 2024-06-09 170/week @ 2024-06-16 204/week @ 2024-06-23 70/week @ 2024-06-30 194/week @ 2024-07-07 127/week @ 2024-07-14 155/week @ 2024-07-21 150/week @ 2024-07-28 95/week @ 2024-08-04 168/week @ 2024-08-11 279/week @ 2024-08-18

每月下载量 710
用于 9 个 Crates

MIT-0 许可证

19KB
155

preferences

Rust 中读取和写入特定用户的应用数据

Crates.io Version Crates.io MSRV Crates.io License Crates.io Total Downloads

docs.rs GitHub Actions Workflow Status Coveralls

文档

https://docs.rs/preferences

安装

cargo add preferences

lib.rs:

读取和写入特定用户的应用数据

该包允许 Rust 开发者以灵活且平台合适的方式存储和检索用户本地首选项和其他应用程序数据。

虽然最初是受 Java 方便的 Preferences API 启发,但此包更加灵活。 任何 实现 serdeSerializeDeserialize 特性的结构体或枚举都可以作为用户数据存储和检索。使用 #[derive(Serialize, Deserialize)] 属性实现这些特性是微不足道的。

用法

为了方便起见,提供了类型 PreferencesMap<T>。实际上它就是 std::collections::HashMap<String, T>,其中 T 默认为 String)。这反映了Java API,它将用户数据建模为一个不透明的键值存储。只要 T 可序列化和反序列化,Preferences 将为你的映射实例实现。这允许你使用来自 Preferencessave(..)load(..) 特性方法无缝地保存和加载用户数据。

基本示例

extern crate preferences;
use preferences::{AppInfo, PreferencesMap, Preferences};

const APP_INFO: AppInfo = AppInfo{name: "preferences", author: "Rust language community"};

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 = "tests/docs/basic-example";
    let save_result = faves.save(&APP_INFO, prefs_key);
    assert!(save_result.is_ok());

    // ... Then do some stuff ...

    // Retrieve the user's preferences
    let load_result = PreferencesMap::<String>::load(&APP_INFO, prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(load_result.unwrap(), faves);

}

使用自定义数据类型

extern crate preferences;
extern crate serde;
use preferences::{AppInfo, Preferences};
use serde::{Serialize, Deserialize};

const APP_INFO: AppInfo = AppInfo{name: "preferences", author: "Rust language community"};

// Deriving `Serialize` and `Deserialize` on a struct/enum automatically implements
// the `Preferences` trait.
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct PlayerData {
    level: u32,
    health: f32,
}

fn main() {

    let player = PlayerData{level: 2, health: 0.75};

    let prefs_key = "tests/docs/custom-types";
    let save_result = player.save(&APP_INFO, prefs_key);
    assert!(save_result.is_ok());

    // Method `load` is from trait `Preferences`.
    let load_result = PlayerData::load(&APP_INFO, prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(load_result.unwrap(), player);

}

使用自定义数据类型与 PreferencesMap 一起使用

extern crate preferences;
extern crate serde;
use preferences::{AppInfo, PreferencesMap, Preferences};
use serde::{Serialize, Deserialize};

const APP_INFO: AppInfo = AppInfo{name: "preferences", author: "Rust language community"};

#[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 = "tests/docs/custom-types-with-preferences-map";
    let save_result = places.save(&APP_INFO, prefs_key);
    assert!(save_result.is_ok());

    let load_result = PreferencesMap::load(&APP_INFO, prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(load_result.unwrap(), places);

}

使用自定义数据类型与可序列化容器一起使用

extern crate preferences;
extern crate serde;
use preferences::{AppInfo, Preferences};
use serde::{Serialize, Deserialize};

const APP_INFO: AppInfo = AppInfo{name: "preferences", author: "Rust language community"};

#[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 = "tests/docs/custom-types-in-containers";
    let save_result = square.save(&APP_INFO, prefs_key);
    assert!(save_result.is_ok());

    let load_result = Vec::<Point>::load(&APP_INFO, prefs_key);
    assert!(load_result.is_ok());
    assert_eq!(load_result.unwrap(), square);

}

内部机制

数据被写入活动用户主目录下的平面文件,该位置由操作系统特定。此位置由 app_dirs 框架和数据类型 UserConfig 决定。在数据目录内,文件存储在一个文件夹层次结构中,该层次结构与传递给 save(..) 的偏好键的清理版本相对应。

数据以JSON格式存储。这有几个优点

  • 人类可读且自描述
  • 比例如XML更紧凑
  • 比例如TOML有更高的采用率和语言兼容性
  • 不依赖于如二进制等一致的内存布局

当然,你可以自己实现 Preferences 并将你的用户数据存储在任何位置和格式中。但这将违背这个库的目的。😊

依赖项

~0.8–12MB
~82K SLoC