7个不稳定版本 (3个重大变更)
新功能 0.3.0 | 2024年8月17日 |
---|---|
0.2.2 | 2024年8月9日 |
0.1.1 | 2024年6月21日 |
0.0.1 | 2024年6月14日 |
#1531 in 数据库接口
每月686次下载
在2个crate中使用(通过slumber_tui)
31KB
287 行
持久化
persisted
是一个Rust库,它使得保存任意程序状态变得简单快捷。其简单灵活的设计意味着你可以自己选择数据存储方案。你告诉persisted
如何保存数据以及你想保存什么,然后它会处理其余的事情。
示例请参阅examples/
目录或文档。
lib.rs
:
persisted
是一个库,用于在程序中持久化任意值,以便稍后轻松恢复。该库的主要目标是
- 明确性:你定义了要持久化的内容及其类型
- 易用性:薄薄的包装使持久化值变得容易
- 灵活性:
persisted
与数据存储无关;你可以使用任何你想要的持久化方案,包括数据库、键值存储等。
persisted
最初是为Slumber设计的,这是一个TUI HTTP客户端。因此,它的主要用例是在用户界面会话之间持久化值。尽管如此,它非常灵活,可以在任何类型的上下文中持久化任何类型的值。支持no_std
意味着它甚至可以在嵌入式环境中使用。
概念
persisted
充当你的值和你的数据存储之间的中间人。你定义你的数据结构和数据应该如何保存,persisted
确保数据被适当地加载和存储。关键概念包括
- 数据包装器:[Persisted]和[PersistedLazy]
- 这些将你的数据包装起来,以自动从存储中恢复和保存值
- 数据存储:任何实现了[PersistedStore]的实现者
- 键:存储中值的唯一标识符。每个持久化值都必须有自己的键。键类型必须实现[PersistedKey]。
它如何工作?
persisted
通过将每个持久化值包装在[Persisted]或[PersistedLazy]中来实现。包装器使用一个键和可选的默认值创建。向存储库发出请求以加载键的最新值,如果存在,则使用该值。每当值被修改时,存储库都会通知新的值以便可以保存(有关“已修改”的更严格定义,请参见[Persisted]或[PersistedLazy])。
因为存储库可以从构造函数和析构函数中访问,所以不能传递它,而必须是静态可达的。为此,最简单的方法是使用存储库的static
或thread_local
定义。
示例
下面是一个非常简单的持久化方案的示例。存储库仅保留一个值。
use core::cell::Cell;
use persisted::{Persisted, PersistedKey, PersistedStore};
/// Store index of the selected person
#[derive(Default)]
struct Store(Cell<Option<usize>>);
impl Store {
thread_local! {
static INSTANCE: Store = Default::default();
}
}
impl PersistedStore<SelectedIndexKey> for Store {
fn load_persisted(_key: &SelectedIndexKey) -> Option<usize> {
Self::INSTANCE.with(|store| store.0.get())
}
fn store_persisted(_key: &SelectedIndexKey, value: &usize) {
Self::INSTANCE.with(|store| store.0.set(Some(*value)))
}
}
/// Persist the selected value in the list by storing its index. This is simple
/// but relies on the list keeping the same items, in the same order, between
/// sessions.
#[derive(PersistedKey)]
#[persisted(usize)]
struct SelectedIndexKey;
#[derive(Clone, Debug)]
#[allow(unused)]
struct Person {
name: String,
age: u32,
}
/// A list of items, with one item selected
struct SelectList<T> {
values: Vec<T>,
selected_index: Persisted<Store, SelectedIndexKey>,
}
impl<T> SelectList<T> {
fn new(values: Vec<T>) -> Self {
Self {
values,
selected_index: Persisted::new(SelectedIndexKey, 0),
}
}
fn selected(&self) -> &T {
&self.values[*self.selected_index]
}
}
let list = vec![
Person {
name: "Fred".into(),
age: 17,
},
Person {
name: "Susan".into(),
age: 29,
},
Person {
name: "Ulysses".into(),
age: 40,
},
];
let mut people = SelectList::new(list.clone());
*people.selected_index.get_mut() = 1;
println!("Selected: {}", people.selected().name);
// Selected: Susan
let people = SelectList::new(list);
// The previous value was restored
assert_eq!(*people.selected_index, 1);
println!("Selected: {}", people.selected().name);
// Selected: Susan
功能标志
persisted
支持以下 Cargo 功能
derive
(默认):启用 derive 宏serde
:启用Serialize/Deserialize
实现
依赖关系
~0.4–0.9MB
~20K SLoC