| Crates.io | field-kinds-derive |
| lib.rs | field-kinds-derive |
| version | 0.3.0 |
| created_at | 2025-12-04 20:08:31.611668+00 |
| updated_at | 2025-12-10 16:54:19.782546+00 |
| description | Proc-macro implementation for field-kinds |
| homepage | |
| repository | https://github.com/niktimf/field-kinds |
| max_upload_size | |
| id | 1966987 |
| size | 145,333 |
Compile-time struct field introspection for Rust.
&'static str#[serde(rename)] and #[serde(rename_all)]#[field_tags("tag1", "tag2")]const FIELDS: &'static [FieldMeta][dependencies]
field-kinds = "0.2"
use field_kinds::{FieldKinds, FieldKindsExt, VisitFields};
#[derive(FieldKinds)]
#[serde(rename_all = "camelCase")]
struct User {
user_id: u64,
user_name: String,
is_active: bool,
#[field_tags("sensitive", "pii")]
email: Option<String>,
}
fn main() {
// Field names
assert_eq!(User::field_names(), vec!["user_id", "user_name", "is_active", "email"]);
// Serialized names (with rename_all applied)
assert_eq!(User::serialized_names(), vec!["userId", "userName", "isActive", "email"]);
// Filter by category
assert_eq!(User::fields_by_category("numeric"), vec!["user_id"]);
assert_eq!(User::fields_by_category("text"), vec!["user_name"]);
assert_eq!(User::fields_by_category("optional"), vec!["email"]);
// Filter by tag
assert_eq!(User::fields_by_tag("sensitive"), vec!["email"]);
// Check field existence
assert!(User::has_field("user_id"));
assert!(!User::has_field("nonexistent"));
// Get field category
assert_eq!(User::field_category("user_id"), Some("numeric"));
// Access static metadata directly
assert_eq!(User::FIELDS.len(), 4);
// Iterate over field metadata
for field in User::FIELDS {
println!("{}: {} [{:?}]", field.name, field.category, field.tags);
}
}
| Attribute | Description |
|---|---|
#[serde(rename_all = "...")] |
Apply case conversion to serialized names |
Supported cases: camelCase, snake_case, PascalCase, SCREAMING_SNAKE_CASE, kebab-case
| Attribute | Description |
|---|---|
#[serde(rename = "...")] |
Override serialized name |
#[field_tags("tag1", "tag2")] |
Add custom tags |
#[field_kinds(skip)] |
Exclude field from introspection |
Types are automatically categorized:
| Category | Types |
|---|---|
numeric |
i8-i128, u8-u128, f32, f64, isize, usize |
text |
String, &str, Box<str>, char |
bool |
bool |
optional |
Option<T> |
collection |
Vec<T>, HashSet<T>, HashMap<K,V>, BTreeSet<T>, BTreeMap<K,V>, [T; N], &[T] |
unknown |
Everything else |
Implement Categorized for your types:
use field_kinds::{Categorized, Numeric};
struct Money(i64);
impl Categorized for Money {
type Category = Numeric;
}
Minimum supported Rust version is 1.90.0 (Rust 2024 edition).
MIT