7 releases (1 stable)

new 1.0.0 May 6, 2025
0.4.2 Apr 25, 2025
0.3.1 Aug 27, 2024
0.1.1 Jun 21, 2024
0.0.1 Jun 21, 2024

#91 in #persistence

Download history 10/week @ 2025-01-18 16/week @ 2025-01-25 46/week @ 2025-02-01 32/week @ 2025-02-08 100/week @ 2025-02-15 57/week @ 2025-02-22 33/week @ 2025-03-01 18/week @ 2025-03-08 70/week @ 2025-03-15 22/week @ 2025-03-22 29/week @ 2025-03-29 66/week @ 2025-04-05 28/week @ 2025-04-12 122/week @ 2025-04-19 95/week @ 2025-04-26 113/week @ 2025-05-03

364 downloads per month
Used in persisted

MIT license

3KB

persisted

Test CI crates.io docs.rs

persisted is a Rust library that makes it easy and quick to save arbitrary program state. Its simple and flexible design means you bring your own data store. You tell persisted how to save data and what you want to save, and it figures out the rest.

persisted was designed for use in TUI programs (specifically Slumber), but can also be used for GUIs or any other applications with distributed state that needs to be persisted.

Here’s an example of a very simple persistence scheme. The store keeps just a single value.

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

For more examples, see the examples/ directory or the documentation.

Dependencies

~190–620KB
~15K SLoC