macro_rules! record { ($(#[$struct_doc:meta])* Name => $name:ident, $($(#[$field_doc:meta])* $fname:ident => $ftype:ty),* $(,)?) => { ... }; ($($(#[$field_doc:meta])* $fname:ident => $ftype:ty),* $(,)?) => { ... }; }
Expand description
Generate an “anonymous” record struct
that implements from_row
.
This is best used for deserializing rows from an ad-hoc query in a strongly typed manner.
Note that the generated struct does not implement Model
, as it can’t be associated with any specific table.
This means that tools like #[bind]
/#[extr]
and the like are not available for records.
However, TryFrom<Row>
is still implemented, making records usable in some generic contexts.
Example
The example assumes this database schema:
CREATE TABLE people (name, age, alive);
record! {
// The provided field name is assumed to map directly to a column in a query's output.
name => String,
age => u16,
}
record! {
// By default, the generated struct is called `Record.`
// This can be overridden with the `Name` parameter, should the need arise.
Name => Age,
age => u16,
}
let mut get_people = conn.prepare("SELECT name, age FROM people")?;
let mut get_ages = conn.prepare("SELECT age FROM people")?;
get_people
.query_and_then([], Record::from_row)?
.map(|record| ...);
get_ages
.query_and_then([], Age::from_row)?
.map(|age| ...);
Notes
Doc comments (and other attributes) are supported:
record! {
/// A person's name.
name => String,
/// A person's age.
age => u16,
}
Additionally, you can apply type-level attributes like derives on the Name
argument.
record! {
#[derive(Debug, Clone)]
Name => Age,
age => u16,
}
(record!
does not apply any derives automatically.)
This does not work without the Name
argument, due to macro limitations - Rust can’t
disambiguate between “attributes for the struct” and “attributes for the field.”
record! {
#[derive(Debug, Clone)]
/// A person's name.
name => String,
/// A person's age.
age => u16,
}