field_kinds/
lib.rs

1#![warn(missing_docs)]
2
3//! Compile-time struct field introspection via derive macro.
4//!
5//! This crate provides the [`FieldKinds`] derive macro that generates
6//! compile-time metadata about struct fields, including their names,
7//! types, categories, and custom tags.
8//!
9//! # Features
10//!
11//! - **Field names**: Get field names as `&'static str`
12//! - **Serialized names**: Supports `#[serde(rename)]` and `#[serde(rename_all)]`
13//! - **Type categories**: Automatic categorization (numeric, text, bool, optional, collection)
14//! - **Custom tags**: Add arbitrary tags to fields via `#[field_tags("tag1", "tag2")]`
15//! - **Static metadata**: All field info available as `const FIELDS: &'static [FieldMeta]`
16//! - **Zero runtime cost**: All metadata is computed at compile time
17//!
18//! # Example
19//!
20//! ```rust
21//! use field_kinds::{FieldKinds, FieldKindsExt, VisitFields};
22//!
23//! #[derive(FieldKinds)]
24//! #[serde(rename_all = "camelCase")]
25//! struct User {
26//!     user_id: u64,
27//!     user_name: String,
28//!     is_active: bool,
29//!     #[field_tags("sensitive", "pii")]
30//!     email: Option<String>,
31//! }
32//!
33//! // Get field names
34//! assert_eq!(User::field_names(), vec!["user_id", "user_name", "is_active", "email"]);
35//!
36//! // Get serialized names (with rename_all applied)
37//! assert_eq!(User::serialized_names(), vec!["userId", "userName", "isActive", "email"]);
38//!
39//! // Filter by category
40//! assert_eq!(User::fields_by_category("numeric"), vec!["user_id"]);
41//! assert_eq!(User::fields_by_category("text"), vec!["user_name"]);
42//!
43//! // Filter by tag
44//! assert_eq!(User::fields_by_tag("sensitive"), vec!["email"]);
45//!
46//! // Check field existence
47//! assert!(User::has_field("user_id"));
48//! assert!(!User::has_field("nonexistent"));
49//!
50//! // Access static metadata directly
51//! assert_eq!(User::FIELDS.len(), 4);
52//! ```
53//!
54//! # Attributes
55//!
56//! ## Struct-level
57//!
58//! - `#[serde(rename_all = "...")]` - Apply case conversion to serialized names
59//!
60//! ## Field-level
61//!
62//! - `#[serde(rename = "...")]` - Override serialized name for a field
63//! - `#[field_tags("tag1", "tag2")]` - Add custom tags to a field
64//! - `#[field_kinds(skip)]` - Skip a field from introspection
65
66mod field_meta;
67
68pub use field_kinds_derive::FieldKinds;
69pub use field_meta::{
70    Bool, Categorized, Collection, FieldCount, FieldInfo, FieldKinds,
71    FieldKindsExt, FieldMeta, HListVisitor, Numeric, Optional, Text,
72    TypeCategory, Unknown, VisitFields,
73};