#[derive(FieldName)]
{
// Attributes available to this derive:
#[stem_name]
#[ste_name]
#[stem_name_derive]
#[ste_name_derive]
#[stem_name_attr]
#[ste_name_attr]
}
Expand description
Generates {StructName}FieldName, an enum whose variants represent struct field names.
For enum variants with values use FieldType instead.
Each non-skipped field becomes a unit variant in PascalCase. The variants are ordered by
field declaration order.
The generated enum derives Debug, PartialEq, Eq, Clone, and Copy by default.
They can be removed by adding no_defaults to the stem_name_derive attribute.
Use #[stem_name_derive(...)] to add more derives - the defaults are merged with whatever
you specify, so you only need to list derives not already in the default set.
§Attributes
| Attribute | Target | Description |
|---|---|---|
#[stem_name(skip)] | field | Exclude this field from the generated enum. |
#[stem_name(nested)] | field | Flatten the nested struct’s FieldName variants into this enum. |
#[stem_name_derive(...)] | struct | Merge additional derives onto the generated enum (defaults are kept). |
#[stem_name_attr(...)] | struct | Extra attributes applied verbatim to the generated enum. |
All stem_name* attributes have short aliases: ste_name, ste_name_derive, ste_name_attr.
§Generated items
For a struct Foo with N non-skipped fields, the macro generates:
enum FooFieldName { Field1, Field2, ... }
impl FieldNames<N> for Foo { ... }§Example
use struct_to_enum::{FieldName, FieldNames};
#[derive(FieldName)]
struct User {
id: u64,
user_name: String,
#[stem_name(skip)]
internal_token: String,
}
// Generated: enum UserFieldName { Id, UserName } (Debug, PartialEq, Eq, Clone, Copy)
let names: [UserFieldName; 2] = User::field_names();
assert_eq!(names, [UserFieldName::Id, UserFieldName::UserName]);§Flattening nested structs
Mark a field with #[stem_name(nested)] to inline the variants of a nested struct
(which must also derive FieldName) directly into the parent enum. Nesting can be
arbitrarily deep.
use struct_to_enum::{FieldName, FieldNames};
#[derive(FieldName)]
pub struct Address {
pub street: String,
pub city: String,
}
#[derive(FieldName)]
struct Person {
name: String,
#[stem_name(nested)]
address: Address,
}
// PersonFieldName: Name, Street, City (Address's variants are inlined)
let fields: [PersonFieldName; 3] = Person::field_names();
assert_eq!(fields, [PersonFieldName::Name, PersonFieldName::Street, PersonFieldName::City]);§Generics
Generic structs are supported. The FieldNames impl carries the same type parameters:
use struct_to_enum::{FieldName, FieldNames};
#[derive(FieldName)]
struct Pair<A, B> {
first: A,
second: B,
}
// Generated: enum PairFieldName { First, Second }
assert_eq!(PairFieldName::First, PairFieldName::First);§Combining with other derives
Use #[stem_name_derive] and #[stem_name_attr] to pass anything to the generated enum.
This works with crates like strum:
use struct_to_enum::FieldName;
use strum_macros::EnumString;
#[derive(FieldName)]
#[stem_name_derive(EnumString)]
#[stem_name_attr(strum(ascii_case_insensitive))]
struct Query {
user_id: u64,
status: String,
}
// Default derives (Debug, PartialEq, Eq, Clone, Copy) are merged with EnumString.
let variant: QueryFieldName = "userid".parse().unwrap(); // case-insensitive
assert_eq!(variant, QueryFieldName::UserId);