#[document_module]Expand description
Orchestrates documentation generation for an entire module.
This macro provides a centralized way to handle documentation for Higher-Kinded Type (HKT) implementations. It performs a two-pass analysis of the module:
- Context Extraction: It scans for
impl_kind!invocations and standardimplblocks to build a comprehensive mapping of associated types (a “projection map”). - Documentation Generation: It processes all methods annotated with
#[document_signature]or#[document_type_parameters], resolvingSelfand associated types using the collected context. - Validation (Optional): Checks that impl blocks and methods have appropriate documentation attributes and emits compile-time warnings for missing documentation.
§Syntax
Due to inner macro attributes being unstable, use the following wrapper pattern:
#[fp_macros::document_module]
mod inner {
// ... module content ...
}
pub use inner::*;To disable validation warnings:
#[fp_macros::document_module(no_validation)]
mod inner {
// ... module content ...
}
pub use inner::*;§Generates
In-place replacement of #[document_signature] and
#[document_type_parameters] attributes with generated documentation
comments. It also resolves Self and Self::AssocType references to their concrete
types based on the module’s projection map.
§Attributes
The macro supports several documentation-specific attributes for configuration:
#[document_default]: (Used insideimplorimpl_kind!) Marks an associated type as the default to use when resolving bareSelfreferences.#[document_use = "AssocName"]: (Used onimplorfn) Explicitly specifies which associated type definition to use for resolution within that scope.
§Validation
By default, document_module validates that impl blocks and methods have appropriate
documentation attributes and emits compile-time errors for missing documentation.
To disable validation, use #[document_module(no_validation)].
§Validation Rules
An impl block should have:
#[document_type_parameters]if it has type parameters#[document_parameters]if it contains methods with receiver parameters (self, &self, &mut self)
A method should have:
#[document_signature]- always recommended for documenting the Hindley-Milner signature#[document_type_parameters]if it has type parameters#[document_parameters]if it has non-receiver parameters
§Examples of Validation
// This will emit warnings:
#[fp_macros::document_module]
mod inner {
pub struct MyType;
// WARNING: Impl block contains methods with receiver parameters
// but no #[document_parameters] attribute
impl MyType {
// WARNING: Method should have #[document_signature] attribute
pub fn process(&self, x: i32) -> i32 { x }
}
}// Properly documented (no warnings):
#[fp_macros::document_module]
mod inner {
pub struct MyType;
#[document_parameters("The MyType instance")]
impl MyType {
#[document_signature]
#[document_parameters("The input value")]
pub fn process(&self, x: i32) -> i32 { x }
}
}// Disable validation to suppress warnings:
#[fp_macros::document_module(no_validation)]
mod inner {
// ... undocumented code won't produce warnings ...
}§Hierarchical Configuration
When resolving the concrete type of Self, the macro follows this precedence:
- Method Override:
#[document_use = "AssocName"]on the method. - Impl Block Override:
#[document_use = "AssocName"]on theimplblock. - (Type, Trait)-Scoped Default:
#[document_default]on the associated type definition in a traitimplblock. - Module Default:
#[document_default]on the associated type definition inimpl_kind!.
§Examples
// Invocation
#[fp_macros::document_module]
mod inner {
use super::*;
impl_kind! {
for MyBrand {
#[document_default]
type Of<'a, T: 'a>: 'a = MyType<T>;
}
}
impl Functor for MyBrand {
#[document_signature]
fn map<'a, A: 'a, B: 'a, Func>(
f: Func,
fa: Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, A>),
) -> Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, B>)
where
Func: Fn(A) -> B + 'a
{
todo!()
}
}
}
pub use inner::*;
// Expanded code
mod inner {
use super::*;
// ... generated Kind implementations ...
impl Functor for MyBrand {
/// `forall a b. (a -> b, MyType a) -> MyType b`
fn map<'a, A: 'a, B: 'a, Func>(
f: Func,
fa: Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, A>),
) -> Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, B>)
where
Func: Fn(A) -> B + 'a
{
todo!()
}
}
}
pub use inner::*;