Expand description
Create a typed embedded database by defining a struct. Interact with the database through getters and setters. Choose how values missing in the database are represented. Standard library types Vec
, HashMap
and Option
have special getters and setters to mimic their standard library functionality. You can push and pop from vecs.
Choose out of various popular key-value databases then instantiate the struct providing only the db path. Alternatively pass any object that implements dbstruct::DataStore
.
How to use derive(dbstruct)
Lets go through an example, there are many more here:
use std::path::Path;
#[dbstruct::dbstruct(db=sled)]
pub struct Test {
#[dbstruct(Default)]
the_awnser: u8,
primes: Vec<u32>,
#[dbstruct(Default="format!(\"{}\", 20+2+20)")]
the_result: String,
}
fn main() {
// a wrapper around a HashMap that implements the
// `DataStore` trait
let db = Test::new(&Path::new("the_db2")).unwrap();
db.the_awnser().set(&42).unwrap();
assert_eq!(42u8, db.the_awnser().get().unwrap());
db.primes().push(&2).unwrap();
db.primes().push(&3).unwrap();
db.primes().push(&5).unwrap();
db.primes().push(&7).unwrap();
assert_eq!(Some(7), db.primes().pop().unwrap());
assert_eq!(String::from("42"), db.the_result().get().unwrap());
}
Here derive(dbstruct)
instructs Rust to transform the input struct to a typed database. Every
field is replaced with a method with the same name that returns a wrapper
. The various attributes used to
customise the generated method.
First, define a struct, whatever its name. This will become your database object. Its fields
will become keys or prefixes in the database. Now add the dbstruct attribute and choose a
database using db=<your chosen database>
. Set db=trait
to use any object you have implemented
dbstructs traits for. Finally determine how to deal with missing values. You can
use the types Default
implementation, generate missing values from an expression or wrap your type in
Option
.
Supported databases
Name | advantage | attribute option |
---|---|---|
Sled | pure Rust | db=sled |
How it works
dbstruct replaces the fields in your struct with methods. Each method returns a wrapper
that allows getting and setting values. While your program runs the fields of a struct are
stored in memory, there values lost the program stops. The wrapper store the values in a
database.
Missing values
When dbstruct can not find a field in the database it needs to know what to return. You must
tell dbstruct how to treat missing values. The simplest way is to wrap your type in an
Option
. Then dbstruct will return None if the value is missing. Alternatively you can instruct dbstruct
to use the types Default
implementation or set an expression to generate a default value.
Special wrapper
Some fields get methods that return special wrapper. These wrappers mimic the fields type and handle missing values on their own. Struct fields with type Vec are transformed into methods that return a Vec wrapper. It allows pushing and popping values. You can opt out of this by defining how to handle missing values (see above)
See wrapper
for a complete list.
Re-exports
Modules
- provides a non peristant store for testing
- You can implement some of these traits to use an unsupported database
- Wrapper are how dbstruct reads and writes to the database. They handle serializing and deserializing, provide the API and determine how to handle missing data.
Enums
- An Error type encapulating various issues that may come up during database operation or (de)serializing