doc_for
[WARNING] This crate is still in development, and the API is subject to BREAKING CHANGES.
📖 Get the documentation comment for structs, enums and unions, in a zero-cost fashion.
🪄 Features
- Zero-cost: All work is done at compile-time
- Simple: Just annotate your struct with
#[doc_impl]and use thedoc_for!macro
🤔 Usage
Get the documentation comment for a type
First, bring doc_for and doc_impl into scope:
use ;
Then, annotate your struct with #[doc_impl]:
# use ;
#
/// Some documentation
Finally, use the doc_for! macro to get the documentation comment, which returns an Option<&'static str>:
# use ;
#
# /// Some documentation
#
#
assert_eq!;
Note that the leading spaces are preserved. Multi-line comments are also supported:
# use ;
#
/// Some documentation
/// that spans multiple lines
///
/// Additional information
assert_eq!;
If the type does not have a documentation comment, doc_for! will return None:
# use ;
#
// No documentation comment here
assert!;
Also works with tuple structs, enums and unions:
# use ;
#
/// Tuple struct documentation
;
assert_eq!;
/// Enum documentation
assert_eq!;
/// Union documentation
union MyUnion
assert_eq!;
Get the documentation comment for fields and variants
Same as before, bring doc_impl and doc_for! into scope and annotate your struct with #[doc_impl]:
use ;
Then, use the doc_for! macro to get the documentation comment. If the field does not have a documentation comment, doc_for! will return None:
# use ;
#
#
#
assert_eq!;
assert!;
If the field or variant does not exist, doc_for! will panic, thus failing the compilation:
# use ;
#
#
#
// Won't compile due to `Field or variant does not exist`
assert_eq!;
Similarly, it also works with union fields (not listed here), enum variants and tuple struct fields:
# use ;
#
assert_eq!;
assert!;
// Won't compile due to `Field or variant does not exist`
// assert_eq!(doc_for!(MyEnum, NonExistent), None);
;
assert_eq!;
assert!;
// Won't compile due to `Field or variant does not exist`
// assert_eq!(doc_for!(MyTupleStruct, 2), None);
Stripping the documentation comment
The strip attribute can be used to strip leading whitespace characters of the documentation comment. If all, all will be stripped; if n, n whitespace characters will be stripped, if present. Default is 0.
use ;
/// Some documentation
assert_eq!;
/// Too many spaces
assert_eq!;
If you don't care about the Option
The doc! macro is basically doc_for! with unwrap:
use ;
assert_eq!;
...So it panics and fails the compilation if the requested type or field is not documented:
# use ;
#
#
#
#
// Won't compile due to `The type is not documented`
println!;
# use ;
#
#
#
#
// Won't compile due to `The field is not documented`
println!;
Of course, trying to access a non-existent field or variant will also fail the compilation:
# use ;
#
#
#
#
// Won't compile due to `Field or variant does not exist`
println!;
Get the documentation comment for an enum variant
This time, bring DocDyn and doc_impl into scope:
use ;
Then, annotate your enum with #[doc_impl(doc_for = false, doc_dyn = true)]:
# use ;
#
Finally, call the doc_dyn method on the enum variant:
# use ;
#
#
#
assert_eq!;
assert!;
Note that this method is not zero-cost, as it matches the enum variant at runtime.
To use both doc_for! and doc_dyn on the same enum, annotate it with #[doc_impl(doc_dyn = true)]. You can include doc_for = true if you want, but since it's the default, it's not necessary.
# use ;
#
assert_eq!;
assert_eq!;
The derive alternative
If you prefer to use derive, you can use DocFor and DocDyn to replace doc_for and doc_dyn fields in the doc_impl attribute:
use ;
/// Some documentation
assert_eq!;
assert_eq!;
assert_eq!;
However, you won't be able to configure the strip attribute in this case.
⚙️ Implementation
DocFor and doc_for!
The doc_for crate provides a DocFor trait and a doc_for! macro:
- The
DocFortrait requires an associated constantDOCto be implemented for the type - Deriving the
DocFortrait sets theDOCconstant as the documentation comment of the type, and generates aconst fn doc_for_field(name) -> Option<&'static str>function- Currently Rust doesn't support constant functions in traits, so the
doc_for_fieldfunction is implemented directly on the annotated type - If the annotated type is a struct, union or enum, the
nameparameter accepts a&'static str - If the annotated type is a tuple struct, the
nameparameter accepts anusize
- Currently Rust doesn't support constant functions in traits, so the
- If given a type, the
doc_for!macro retrieves the value of this constant; If given a type and a field name, thedoc_for!macro calls thedoc_for_fieldfunction with the given field name
Using these APIs is zero-cost, as all the work is done at compile-time:
- When compiled, types that derive
DocForwill have their documentation comments inlined as associated constants or in constant functions - Calls to
doc_for!will be replaced with the value of the associated constant or the result of the constant function
DocDyn and doc_dyn
The doc_for crate also provides a DocDyn trait and a doc_dyn method:
- The
DocDyntrait requires adoc_dynmethod to be implemented for the type, which returns anOption<&'static str> - Deriving the
DocDyntrait generates adoc_dynmethod, which returns the documentation comment that matches the variant of the enum
This method is not zero-cost, as it matches the enum variant at runtime.
doc_impl
The doc_impl attribute is used to derive the DocFor and DocDyn traits for a type, along with configuring the strip attribute.
✅ TODO
- Strip each line of the documentation comment, via a
stripattribute - Better error reporting and handling
- Access module documentation (e.g.
doc_for!(my_module)) - Access trait documentation (e.g.
doc_for!(MyTrait)) - Access sub-item documentation
- Access field documentation (e.g.
doc_for!(MyStruct, field)ordoc_for!(MyUnion, field)) - Access tuple struct field documentation (e.g.
doc_for!(MyTupleStruct, 0)) - Access enum variant documentation (statically) (e.g.
doc_for!(MyEnum, Variant)) - Access enum variant documentation (dynamically) (e.g.
doc_for!(my_enum_variant)) - Access method documentation (e.g.
doc_for!(MyStruct, method)) - Access associated constant documentation (e.g.
doc_for!(MyStruct, CONSTANT)) - Access associated type documentation (e.g.
doc_for!(MyStruct, Type))
- Access field documentation (e.g.