macro_rules! finite_set {
(
$(#[$name_meta:meta])*
$name:ident,
$(#[$table_meta:meta])*
$table:ident {
$($(#[$variant_meta:meta])* $variant:ident $(= $value:tt)? as $field:tt),+ $(,)?
}
) => { ... };
(
$(#[$name_meta:meta])*
$name:ident,
$(#[$table_meta:meta])*
$table:ident {
$($(#[$variant_meta:meta])* $variant:ident $(= $value:tt)? as $field:tt),+ $(,)?
},
$cursor:ident
) => { ... };
(
$(#[$name_meta:meta])*
$name:ident,
$(#[$record_meta:meta])*
$record:ident,
$(#[$table_meta:meta])*
$table:ident,
{
$($(#[$variant_meta:meta])* $variant:ident $(= $value:tt)? as $field:ident),+ $(,)?
}
) => { ... };
(
@table
$len:expr,
{ $(#[$name_meta:meta])* },
$name:ident,
{ $(#[$table_meta:meta])* },
$table:ident,
$table_expr:ident {
$($(#[$variant_meta:meta])* $variant:ident $(= $value:tt)? as $field:tt),+ $(,)?
}
) => { ... };
(
@record
$len:expr,
{ $(#[$name_meta:meta])* },
$name:ident,
{ $(#[$record_meta:meta])* },
$record:ident,
{ $(#[$table_meta:meta])* },
$table:ident,
{
$($(#[$variant_meta:meta])* $variant:ident $(= $value:tt)? as $field:ident),+ $(,)?
}
) => { ... };
(
@cursor
$len:expr,
$name:ident,
$cursor:ident
) => { ... };
(@count $($variant:ident),+) => { ... };
(@unit $variant:ident) => { ... };
(@name $field:ident) => { ... };
(@name $field:literal) => { ... };
}Expand description
Defines a small finite enum, its table type, and optionally its record type.
This macro keeps enum-indexed tables usable in const contexts. It works around current Rust const-fn limitations by generating inherent const helpers instead of relying only on trait methods and indexing operators.
Every variant must have an as label. The label becomes the canonical
string returned by name() and written by Display.
Table-only form:
finite_set!(
/// Board square.
Square,
/// Array-backed table keyed by square.
SquareTable {
/// Lower-left square from White's perspective.
A1 = 0 as a1,
B1 = 1 as b1,
}
);Table-only form with cursor:
finite_set!(
File,
FileTable {
A = 0 as a,
B = 1 as b,
},
FileCursor
);Attributes are optional at every documented position. Values are optional when the previous variant’s discriminant plus one is the desired value:
finite_set!(Square, SquareTable {
A1 = 0 as a1,
B1 as b1,
});Record form:
finite_set!(
/// Player to move / piece owner.
Player,
/// Named-field values keyed by player.
Players,
/// Array-backed table keyed by player.
PlayerTable,
{
/// Black player.
Black = 0 as black,
/// White player.
White = 1 as white,
}
);The generated enum gets:
ALLandLENname,eq,index,from_index, andpanicky_from_indexiteranditer_revDisplayvianame
The generated table type is an alias for Table and gets key-based
indexing plus get, get_ref, and get_mut.
The record form also generates a named-field struct with the same key-based indexing and accessors.
The public arms calculate the enum length with @count, then dispatch to
private arms. @table emits the enum, FiniteSet, and the array-backed
table alias. @record first delegates to @table, then adds the named-field
record and its indexing helpers.