persy 1.5.0

Transactional Persistence Engine
Documentation
use serde_derive::{Deserialize, Serialize};
use std::path::Path;

#[derive(Serialize, Deserialize)]
struct MyCfg {
    name: String,
    value: u32,
}

#[derive(Debug)]
enum Error {
    Persy(persy::PersyError),
    Serde(serde_json::Error),
}

///
/// Delete the persistent configuration a recreate the new configuration all inside the same
/// transaction guaranteeing atomicity of the operation
///
///
fn update_cfg(persy: &persy::Persy, cfg: MyCfg) -> Result<(), Error> {
    let mut tx = persy.begin()?;
    for (id, _) in persy.scan("cfg")? {
        tx.delete("cfg", &id)?;
    }
    let rec = serde_json::to_vec(&cfg)?;
    tx.insert("cfg", &rec)?;
    tx.prepare()?.commit()?;
    Ok(())
}
///
/// Read the configuration from the persistent file
///
fn read_cfg(persy: &persy::Persy) -> Result<Option<MyCfg>, Error> {
    for (_, content) in persy.scan("cfg")? {
        let val: MyCfg = serde_json::from_slice(&content)?;
        return Ok(Some(val));
    }
    Ok(None)
}

///
/// Example of storing configuration in a persy file using a transaction and serializing the
/// information with serde.
///
/// Fairly useful if there is a lot of configurations information that need to be persisted with a
/// guarantee that all or none is written also in case of crash
///
///
///
fn main() {
    let create_segment;
    if !Path::new("my.cfg").exists() {
        persy::Persy::create("my.cfg").expect("create file correctly");
        create_segment = true;
    } else {
        create_segment = false;
    }

    let persy = persy::Persy::open("my.cfg", persy::Config::new()).expect("open file correctly");
    if create_segment {
        let mut tx = persy.begin().expect("begin tx correctly");
        tx.create_segment("cfg").expect("create segment correctly");
        let prepared = tx.prepare().expect("prepare commit correctly");
        prepared.commit().expect("tx committed correctly");
    }

    let cfg = MyCfg {
        name: "some".into(),
        value: 10,
    };

    update_cfg(&persy, cfg).expect("cfg updated");
    let read = read_cfg(&persy).expect("cfg read").expect("is some");
    println!(" name {} value {}", read.name, read.value);

    let cfg = MyCfg {
        name: "other".into(),
        value: 42,
    };

    update_cfg(&persy, cfg).expect("cfg updated");
    let read = read_cfg(&persy).expect("cfg read").expect("is some");
    println!(" name {} value {}", read.name, read.value);
}

impl From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        Error::Serde(err)
    }
}

impl<T: Into<persy::PersyError>> From<persy::PE<T>> for Error {
    fn from(err: persy::PE<T>) -> Error {
        Error::Persy(err.error().into())
    }
}