MVDB - Atomic, Easy to use, File backed storage using Serde


#1

Hey all, I put this together after writing more or less the same boilerplate code over and over in projects for holding some kind of state in a persistent file. It is meant to be used in cases where something like diesel might be overkill, e.g. early in a project, for a small tool only run occasionally, or where the number of reads far outweigh the number of writes.

Here it is on:

It uses serde_json to store the contents of a data structure to a persistent file, provides atomic transactions (via closures) for read-only or read-write access, and allows the user to store the data in either compact or pretty-print JSON.

So far I’ve used this for a couple of command line tools that have a persistent (but modifiable) configuration file, as well as with a small web server backed by rocket, to provide thread-safe access to data across API calls.

Heres a small example of how it is used:

[macro_use] extern crate serde_derive;
extern crate serde;
extern crate mvdb;

use std::path::Path;
use mvdb::Mvdb;

#[derive(Deserialize, Serialize)]
struct DemoData {
    foo: String,
    bar: Vec<u8>,
    baz: String,
}

fn main() {
    let file = Path::new("demo.json");
    let my_data: Mvdb<DemoData> = Mvdb::from_file(&file)
        .expect("File does not exist, or schema mismatch");

    // Read access
    let foo_from_disk = my_data.access(|db| db.foo.clone())
        .expect("Failed to access file");

    // Write access
    my_data.access_mut(|db: &mut DemoData| {
        db.baz = "New Value".into();
    }).expect("Failed to access file");
}

Let me know if you have any questions, or suggestions for improvement!