Expand description
Rustbreak
Rustbreak was a Daybreak inspired single file Database. It has now since evolved into something else. Please check v1 for a more similar version.
You will find an overview here in the docs, but to give you a more complete tale of how this is used please check the examples.
At its core, Rustbreak is an attempt at making a configurable general-purpose store Database. It features the possibility of:
- Choosing what kind of Data is stored in it
- Which kind of Serialization is used for persistence
- Which kind of persistence is used
This means you can take any struct you can serialize and deserialize and stick it into this Database. It is then encoded with Ron, Yaml, JSON, Bincode, anything really that uses Serde operations!
There are three helper type aliases MemoryDatabase, FileDatabase,
and PathDatabase, each backed by their respective backend.
The MemoryBackend saves its data into a Vec<u8>, which is not that
useful on its own, but is needed for compatibility with the rest of the
Library.
The FileDatabase is a classical file based database. You give it a path
or a file, and it will use it as its storage. You still get to pick what
encoding it uses.
The PathDatabase is very similar, but always requires a path for
creation. It features atomic saves, so that the old database contents won’t
be lost when panicing during the save. It should therefore be preferred to a
FileDatabase.
Using the Database::with_deser and Database::with_backend one can
switch between the representations one needs. Even at runtime! However this
is only useful in a few scenarios.
If you have any questions feel free to ask at the main repo.
Quickstart
Add this to your Cargo.toml:
[dependencies.rustbreak]
version = "2"
features = ["ron_enc"] # You can also use "yaml_enc" or "bin_enc"use rustbreak::{deser::Ron, MemoryDatabase};
let db = MemoryDatabase::<HashMap<u32, String>, Ron>::memory(HashMap::new())?;
println!("Writing to Database");
db.write(|db| {
db.insert(0, String::from("world"));
db.insert(1, String::from("bar"));
});
db.read(|db| {
// db.insert("foo".into(), String::from("bar"));
// The above line will not compile since we are only reading
println!("Hello: {:?}", db.get(&0));
})?;Or alternatively:
use rustbreak::{deser::Ron, MemoryDatabase};
let db = MemoryDatabase::<HashMap<u32, String>, Ron>::memory(HashMap::new())?;
println!("Writing to Database");
{
let mut data = db.borrow_data_mut()?;
data.insert(0, String::from("world"));
data.insert(1, String::from("bar"));
}
let data = db.borrow_data()?;
println!("Hello: {:?}", data.get(&0));Error Handling
Handling errors in Rustbreak is straightforward. Every Result has as its
fail case as error::RustbreakError. This means that you can now either
continue bubbling up said error case, or handle it yourself.
use rustbreak::{deser::Ron, error::RustbreakError, MemoryDatabase};
let db = match MemoryDatabase::<usize, Ron>::memory(0) {
Ok(db) => db,
Err(e) => {
// Do something with `e` here
std::process::exit(1);
}
};Panics
This Database implementation uses RwLock and Mutex under the hood.
If either the closures given to Database::write or any of the Backend
implementation methods panic the respective objects are then poisoned. This
means that you cannot panic under any circumstances in your closures or
custom backends.
Currently there is no way to recover from a poisoned Database other than
re-creating it.
Examples
There are several more or less in-depth example programs you can check out! Check them out here: Examples
config.rsshows you how a possible configuration file could be managed with rustbreakfull.rsshows you how the database can be used as a hashmap storeswitching.rsshow you how you can easily swap out different parts of the Database Note: To run this example you need to enable the featureyamllike so:cargo run --example switching --features yamlserver/is a fully fledged example app written with the Rocket framework to make a form of micro-blogging website. You will need rust nightly to start it.
Features
Rustbreak comes with following optional features:
ron_encwhich enables the Ron de/serializationyaml_encwhich enables the Yaml de/serializationbin_encwhich enables the Bincode de/serialization- ‘mmap’ whhich enables memory map backend.
Enable them in your Cargo.toml file to use them. You can
safely have them all turned on per-default.
Re-exports
pub use crate::deser::DeSerializer;pub use crate::error::*;Modules
The persistence backends of the Database.
Different serialization and deserialization methods one can use
The rustbreak errors that can be returned
Structs
The Central Database to Rustbreak.
Type Definitions
A database backed by a file.
A database backed by a byte vector (Vec<u8>).
A database backed by a file, using atomic saves.