macro_rules! sql_enum { ($(#[$enum_doc:meta])* Name => $name:ident, $($(#[$variant_doc:meta])* $vname:ident),* $(,)?) => { ... }; }
Expand description
Generate an SQL-compatible field-less enum.
SQL compatible means:
#[repr(i64)]- the equivalent of SQLite’sINTEGERtype.- Implements
TryFrom<i64>. - Implements
ToSqlandFromSql.
(Additionally, the standard constellation of Debug/Clone/Copy/Eq/Hash are derived.)
An enum generated by this macro can be used in any Model implementor.
Usage
sql_enum! {
Name => Color,
Red,
Green,
Blue,
};Notes
Explicit discriminants are not supported. Variants will always be implicitly numbered, in order of definition, from zero.
Concretely, this means that:
ⓘ
sql_enum! {
Name => Color,
Red = 1,
Green = 2,
Blue = 3
}…will not compile.
This is because the TryFrom<i64> implementation generated by the macro looks something like this:
ⓘ
fn try_from(value: i64) -> Result<Self, Self::Error> {
// This gets constant folded, even in debug.
let len = [/* generated array of all possible variants */].len() as i64;
if (0..len).contains(&value) {
// SAFETY: the sql_enum macro does not support explicit discriminants,
// so we know that the enum must be represented by the range 0..len
//
// https://doc.rust-lang.org/reference/items/enumerations.html#implicit-discriminants
Ok(unsafe {
std::mem::transmute(value)
})
}
else {
// Throw error
}
}TL;DR - macro limitations.
Doc comments (and other attributes, like derives) are supported:
sql_enum! {
/// An RGB color tag.
Name => Color,
/// Red
Red,
/// Green
Green,
/// Blue
Blue,
}