Describer
This crate provides human-readable type descriptions through the Describer trait and its derive macro.
Overview
describer allows you to generate string representations of Rust types at compile time. This is useful for documentation, debugging, API introspection, code generation, and understanding complex type hierarchies.
Breaking Changes
v0.3redefines completely how the data is output and allows for nested type description;
Features
- Automatic derive macro for
structsandenums.uniontypes are not supported. - Built-in implementations for primitives, standard library types, and popular third-party crates.
- Field-level attributes for customization (
skip,as,rename.) - Compact notation for common patterns (e.g.,
Option<T>→T?.) - Optional feature flags for third-party integrations.
Installation
Add this to your Cargo.toml:
[]
= "0.3"
For third-party type support, enable the relevant features:
[]
= { = "0.1.0", = ["chrono", "uuid", "regex"] }
Available Features
chrono- Support forDateTime,NaiveDate,NaiveDateTime,NaiveTime.uuid- Support forUuid.regex- Support forRegex.http- Support for HTTP types (Request,Response,HeaderMap, etc.).tokio- Support for Tokio'sMutexandRwLock.indexmap- Support forIndexMapandIndexSet.dashmap- Support forDashMapandDashSet.
Basic Usage
use ;
use HashMap;
// Primitives
assert_eq!;
assert_eq!;
// Standard library types
assert_eq!;
assert_eq!;
assert_eq!;
// Custom types with derive macro
assert_eq!;
Type Notation
The crate uses a compact notation system for common patterns:
| Type | Notation | Example |
|---|---|---|
Optional |
T? |
i32? |
Result |
!{T, E} |
!{String, i32} |
Vec/Slice |
[T] |
[u8] |
HashMap/BTreeMap |
{K: V} |
{String: i32} |
HashSet/BTreeSet |
#{T} |
#{String} |
BinaryHeap |
^[T] |
^[i32] |
Box |
*T |
*u8 |
Arc |
arc T |
arc String |
Rc |
rc T |
rc i32 |
Cell/RefCell |
&T |
&u32 |
Cow |
~T |
~String |
Range types |
[T[, [T], etc. |
[i32[ |
Derive Macro
Structs
The derive macro works with named, unnamed (tuple), and unit structs:
use ;
// Named struct
assert_eq!;
// Tuple struct
;
assert_eq!;
// Unit struct
;
assert_eq!;
Enums
Enums are represented with all their variants separated by |:
use ;
assert_eq!;
Field Attributes
Customize field descriptions using the #[describe(...)] attribute:
skip - Omit a field
use ;
assert_eq!;
with = "..." - Use a custom type name
Replaces the actual type with a custom string:
use ;
assert_eq!;
rename = "..." - Rename the field
Changes the field name in the output (note: the actual attribute is rename, though as can be used for type names):
use ;
assert_eq!;
Combining Attributes
use ;
assert_eq!;
Built-in Type Support
Primitives
All Rust primitives are supported: i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64, bool, char, String, str
Standard Library Collections
- Sequences:
Vec<T>,VecDeque<T>,LinkedList<T>,BinaryHeap<T>,[T] - Maps:
HashMap<K, V>,BTreeMap<K, V> - Sets:
HashSet<T>,BTreeSet<T>
Smart Pointers & Concurrency
- Owned:
Box<T>,Arc<T>,Rc<T> - Interior Mutability:
Cell<T>,RefCell<T>,Mutex<T>,RwLock<T> - Copy-on-Write:
Cow<T>
Ranges
All range types: Range<T>, RangeFrom<T>, RangeTo<T>, RangeInclusive<T>, RangeToInclusive<T>, RangeFull
Tuples
Tuples up to 12 elements are supported:
use ;
assert_eq!;
Third-Party Types (with features)
When enabled via feature flags:
- chrono:
DateTime<Tz>,NaiveDate,NaiveDateTime,NaiveTime - uuid:
Uuid - regex:
Regex - http:
Request<T>,Response<T>,HeaderMap,Method,Uri,StatusCode,Version,Extensions - tokio:
tokio::sync::Mutex<T>,tokio::sync::RwLock<T> - indexmap:
IndexMap<K, V>,IndexSet<T> - dashmap:
DashMap<K, V>,DashSet<T>
Use Cases
API Documentation
Generate human-readable type signatures for API endpoints:
use ;
Schema Generation
use ;
use HashMap;
// DatabaseRecord::describe(), "DatabaseRecord { id: UUID, created_at: Timestamp, data: {String: String} }"
Type Introspection
use ;
Limitations
- No generics support: The current version does not support generic types in custom structs/enums
- No lifetime support: Lifetimes are not included in descriptions
- Unions not supported: Only structs and enums can use the derive macro
Examples
Complex Nested Types
use ;
use ;
use HashMap;
type ComplexType = ;
assert_eq!;
Real-World Example
use ;
use HashMap;
println!;
// Config: "ApiConfig { base_url: URL, timeout: Milliseconds, retry_count: u32, headers: {String: String} }"
assert_eq!;
println!;
// Response: "ApiResponse { Success { data: [u8], timestamp: UnixTimestamp } | Error { code: u16, message: String } }"
assert_eq!;
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
TODO:
- [] Support generic types
- [] Allow remote implementation, like
#[serde(remote = "...")]