8 releases (breaking)
0.7.0 | Sep 2, 2024 |
---|---|
0.6.0 | Sep 2, 2024 |
0.5.0 | Aug 26, 2024 |
0.4.0 | Aug 13, 2024 |
0.1.0 | Aug 7, 2024 |
#9 in #redb
837 downloads per month
Used in redb_model
26KB
566 lines
Redb Model
A derive macro for generating redb
table definitions and DTO object
conversion methods/implementations.
Functionality
This crate aims to unify database entry DTO definitions and redb::TableDefinition
.
Decorating a struct with #[derive(Model)]
will implement Model
for the type,
define redb::TableDefinition
as an associated constant, and generating helper
methods for the type.
Example
#[derive(Model)]
struct User {
#[entry(position(key))]
id: u32,
#[entry(position(value))]
name: String,
#[entry(position(value))]
email: String,
}
let user = User {
id: 0,
name: "User".to_owned(),
email: "user_email@email.com".to_owned(),
};
let txn = db.begin_write().unwrap();
{
let mut table = txn.open_table(User::DEFINITION).unwrap();
let (k, v) = user.as_values();
table.insert(k, v).unwrap();
}
txn.commit().unwrap();
Specifying keys and values
Key(s) and value(s) are specified by decorating table fields with
#[entry(position(...))]
, passing either key
or value
to the inner field.
A composite key/value will be combined into a tuple.
#[derive(Model)]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
#[entry(position(value))]
email: String,
}
let user_key = [0; 16];
let user_value = ("my_name".to_string(), "my_email@email.com".to_string());
let user = User::from_values((user_key, user_value));
let (k, v) = user.into_values();
// Only the value is a tuple for this model.
assert_eq!(k, [0; 16]);
assert_eq!(v, ("my_name".to_string(), "my_email@email.com".to_string()));
Specifying a table name
Table names default to the (case-sensitive) struct name. This can be overridden by decorating
the struct with #[model(name = "...")]
attribute.
#[derive(Model)]
#[model(name = "user_table")]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
}
assert_eq!(User::DEFINITION.name(), "user_table");
Type conversion
The generated implementation of the Model
trait provides methods for
instantiating, borrowing and taking the key/value pairs of the model DTO.
Decorating the struct with #[model(impl_from)]
will further implement
From<T>
, mapping T
to the from_values(T)
and from_guards(T)
methods.
#[derive(Model)]
#[model(impl_from)]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
#[entry(position(value))]
email: String,
}
let user_key = [0; 16];
let user_value = ("my_name".to_string(), "my_email@email.com".to_string());
let user: User = ((user_key, user_value)).into();
Implementation details
The following are general notes regarding implementation.
String
Table Definitions
redb_model
will replace String
with &str
for table definitions. This
is so that composite (tuple) variables can be borrowed and passed to database
handlers without destructuring the DTO. This is not currently possible with
String
.
const TABLE: TableDefinition<(String, String), ()> = TableDefinition::new("table");
let string_0 = "string_0".to_string();
let string_1 = "string_1".to_string();
let txn = db.begin_write().unwrap();
let mut table = txn.open_table(TABLE).unwrap();
// This doesn't work.
table.insert((&string_0, &string_1), ());
// Neither does this.
table.insert((string_0.as_str(), string_1.as_str()), ());
```rust
### Unit type values
The unit type `()` must be passed if no value is defined.
```rust
#[derive(Model)]
#[model(name = "outbound_edge")]
struct Edge {
#[entry(position(key))]
source: [u8; 16],
#[entry(position(key))]
target: [u8; 16],
}
let k = ([0; 16], [1; 16]);
let v = ();
let e = Edge::from_values((k, v));
Variable Ordering
All composite key/value variables are combined as a tuple in the order they are defined. This is intended but can be changed if there is any reason to do so.
The Model
definition and redb::TableDefinition
The redb::TableDefinition
uses 'static
references of the types defined
in the Model
, with the exception of String
which uses a 'static
string
slice. This is to ensure that calling as_values
returns references suitable
for database calls.
License: MIT OR Apache-2.0
lib.rs
:
Derive macro for the redb_model
crate.
Dependencies
~1.2–1.7MB
~40K SLoC