Crates.io | redb_model |
lib.rs | redb_model |
version | 0.10.0 |
source | src |
created_at | 2024-08-07 11:28:04.581305 |
updated_at | 2024-10-18 06:40:07.629382 |
description | Redb model derive macro and DTO type conversion |
homepage | |
repository | https://github.com/cedtwo/redb_model.git |
max_upload_size | |
id | 1328310 |
size | 30,674 |
A derive macro for generating [redb
] table definitions and DTO object
conversion methods/implementations.
At a minimum, deriving Model
on a named struct
will implement the [Model
]
trait, declaring redb::TableDefinition
as an associated constant.
#[derive(Model)]
struct User {
#[entry(position = "key")]
id: u32,
#[entry(position = "value")]
name: String,
#[entry(position = "value")]
email: String,
}
// redb::TableDefinition::<u32, (String, String)>
assert_eq!(User::DEFINITION.name(), "User");
In the example below, the table name is specified as "outbound_edge", and the
label
field is declared as &str
, rather than String
in the table. The
impl_ext
argument on the struct generates an implementation of [ModelExt
],
giving access to methods for type conversion between the DTO types and those
of the redb
key/value. In this case, calling any of the as_
methods will
Copy
the u32
fields, and borrow the String
field as a &str
.
#[derive(Model, Debug, PartialEq, Eq)]
#[model(name = "outbound_edge", impl_ext)]
struct Edge {
#[entry(position = "key")]
source: u32,
#[entry(position = "key")]
target: u32,
#[entry(position = "value", redb_type = "&str")]
label: String,
}
// redb::TableDefinition::<(u32, u32), &str>
assert_eq!(Edge::DEFINITION.name(), "outbound_edge");
let edge0 = Edge {
source: 0,
target: 1,
label: String::from("label"),
};
let txn = db.begin_write().unwrap();
{
// Model::DEFINITION
let mut table = txn.open_table(Edge::DEFINITION).unwrap();
// ModelExt::as_key_and_value
let (k, v) = edge0.as_key_and_value();
table.insert(k, v).unwrap();
}
txn.commit().unwrap();
// ModelExt::as_key
let k = edge0.as_key();
let txn = db.begin_read().unwrap();
// Model::DEFINITION
let table = txn.open_table(Edge::DEFINITION).unwrap();
let edge1 = table
.get(k)
.unwrap()
// ModelExt::from_key_and_guard
.map(|guard| Edge::from_key_and_guard((k, &guard)))
.unwrap();
assert_eq!(edge0, edge1);
A model can be customized with the model
attribute, providing any of the
following arguments:
Argument | Description | Type | Default |
---|
table_name
| The table name passed to the definition | Literal
| <struct name>
(case-sensitive)
table_type
| Table type, either table
or multimap
| Literal
| table
impl_ext
| Implement [ModelExt
] for the type | bool
| false
impl_from
| Implement From<T>
, mapping T
to ModelExt::from_values(T)
and ModelExt::from_guards(T)
. | bool
| false
Note that impl_from
uses methods of impl_ext
and therefore requires both
arguments to be specified.
Values can be customized with the entry
attribute. Each field must specify
position
as key
or value
, and (optionally) provide an alternate redb_type
.
When generating a ModelExt
definition (providing impl_ext
as a struct argument),
from
and into
operations may need to be explicit. Note that composite
variables (multiple key
or value
fields) are combined as tuples in the order
they are defined.
Argument | Description | Type | Default |
---|
position
| The position of the field in an entry, either a key
or a value
. | enum
(key
or value
) | None
redb_type
| The type defined in the redb::TableDefinition
or redb::MultimapTableDefinition
. | Type
| Field Type
from
| The operation to convert from the redb_type
. | Expression
| See below.
into
| The operation to convert into the redb_type
. | Expression
| See below.
Conversion from
a redb
value has the following default behavior (impl_ext
only):
redb_type
is specified, the value is assumed to implement Copy
and passed directly to the DTO.redb_type
is a reference (is prefixed by &
), to_owned
is called on the value.redb_type
is not a reference, into
is called on the value.Conversion into
a redb
value takes a type reference, and has the following default behavior (impl_ext
only):
redb_type
is specified, the value is assumed to implement Copy
and dereferenced.redb_type
is a reference (is prefixed by &
), the value is passed as a reference.redb_type
is not a reference, into
is called on the value.For user defined types, typically implementing From<RedbType> for FieldType
and
Into<RedbType> for &FieldType
will satisfy type conversion.
#[derive(Copy, Clone)]
struct Wrapper(u32);
// Default `from` operation for `Wrapper`.
impl From<u32> for Wrapper {
fn from(value: u32) -> Self {
Wrapper(value)
}
}
// Default `into` operation for `&Wrapper`.
impl Into<u32> for &Wrapper {
fn into(self) -> u32 {
self.0
}
}
#[derive(Model)]
#[model(impl_ext)]
struct MyModel {
#[entry(position = "key", redb_type = "u32")]
key3: Wrapper
}
For external types where a newtype wrapper is not desired, or where the type
does not implement Copy
, the from
and into
operations must be explicit.
Both the from
and into
argument accept a variable named after the field. For
from
expressions, this argument is the redb_type
, while for into
expressions,
this is a reference of the field value. Note that while the operations are
named from
and into
, there is no constraint on what operations can be used,
as is demonstrated below.
use secrecy::{ExposeSecret, SecretString};
use uuid::Uuid;
#[derive(Model)]
#[model(impl_ext)]
struct SecretModel {
#[entry(
position = "key",
redb_type = "[u8; 16]",
from = "Uuid::from_bytes(id)", // `id` is the `redb_type` (`[u8; 16]`).
into = "id.into_bytes()" // `id` is `&Uuid`.
)]
id: Uuid,
#[entry(
position = "value",
redb_type = "&str",
from = "SecretString::from(secret)", // `secret` is the `redb_type` (`&str`).
into = "secret.expose_secret()" // `secret` is `&SecretString`.
)]
secret: SecretString,
}
Generated definitions of the [ModelExt
] traits defines type aliases for the
common key and value tuples used extensively in generated code. These may be
useful for extending the functionality of models without explicitly stating
key/value types.
Alias | Description |
---|
ModelExt::RedbKey
| The K
argument for the given redb
definition.
ModelExt::RedbValue
| The V
argument for the given redb
definition.
ModelExt::ModelKey
| A tuple of the owned key type(s) defined in the model.
ModelExt::ModelValue
| A tuple of the owned value type(s) defined in the model.
License: MIT OR Apache-2.0