在宏中生成文档

dna*_*naq 25 macros rust

在定义表单的某些元组结构时,我有几个宏来减少样板:

macro_rules! new_type (($name:ident, $bytes:expr) => (
    pub struct $name(pub [u8; $bytes]);
    // some common operations on $name
));
Run Code Online (Sandbox Code Playgroud)

但是,我还要记录这些新结构.如果我能在宏调用之前编写我的文档,最好的事情就是.

/// A certain type
new_type!(CertainType, 42);
Run Code Online (Sandbox Code Playgroud)

但是,Rust不会生成CertainType发生这种情况的文档.

另一种(不那么灵活)替代方案是做类似的事情:

macro_rules! new_type (($name:ident, $bytes:expr) => (
    /// Some more generic documentation for $name 
    pub struct $name(pub [u8; $bytes]);
    // some common operations on $name
));
Run Code Online (Sandbox Code Playgroud)

但是,在执行此操作时,Rust宏系统不会$name在文档注释中展开令牌.剩下的唯一选择是在宏中编写非常通用的文档,但这会导致我的库文档记录得比它更糟糕.

您对此有何建议?对我来说最好的解决方案是能够为每个宏调用编写特定的文档,但如果不可能,我会很感激有关如何在文档注释中扩展标记的提示.

Vla*_*eev 29

可以在宏调用中捕获doc注释.它并不广为人知,但Rust文档实际上表示为项目上的一种特殊属性.例如:

/// Some documentation comment
pub fn function() {}

// is equivalent to

#[doc="Some documentation comment"]
pub fn function() {}
Run Code Online (Sandbox Code Playgroud)

可以捕获在宏属性.已经有几个使用此功能的宏,最常用的可能是bitflags!:

macro_rules! bitflags {
    (
        $(#[$outer:meta])*
        pub struct $BitFlags:ident: $T:ty {
            $(
                $(#[$inner:ident $($args:tt)*])*
                const $Flag:ident = $value:expr;
            )+
        }
    ) => { /* ... */ };
    // ...
}
Run Code Online (Sandbox Code Playgroud)

注意图案的部分$(#[$outer:meta])*$(#[$inner:meta])*部分.它们捕获放置在模式中相应项目之前的所有属性.如果你在那里写一个doc注释,它将被转换为doc属性,并像往常一样传递给rustdoc.

以下是来自quick_error使用此方法的箱子的示例:

quick_error! {
    #[derive(Debug)]
    pub enum SomeError {
        /// IO Error
        Io(err: io::Error) {}
        /// Arbitrary system error
        Sys(errno: nix::Errno) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

它确实有效 - quick_error宏生成的结构的一个例子,是它的定义.

  • @ErichGubler 已修复 (2认同)