在宏中生成文档

问题描述 投票:0回答:2

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

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

但是,我还想记录这些新结构。最好的事情是如果我可以在宏调用之前编写文档。

/// A certain type
new_type!(CertainType, 42);

但是,当发生这种情况时,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
));

但是,执行此操作时,Rust 宏系统不会扩展文档注释中的标记

$name
。剩下的唯一选择是在宏中编写非常通用的文档,但这会导致我的库的文档记录比应有的要糟糕得多。

您对处理这个问题有什么建议?对我来说最好的解决方案是能够为每个宏调用编写特定的文档,但如果不可能,我将不胜感激有关如何在文档注释中扩展标记的提示。

macros rust
2个回答
73
投票

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

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

// is equivalent to

#[doc="Some documentation comment"]
pub fn function() {}

并且可以捕获宏中的属性。已经有几个宏使用此功能,最常用的可能是 bitflags!

:

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

注意图案的

$(#[$outer:meta])*

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

以下是来自

quick_error

 板条箱的示例,它也使用了这种方法:

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

它确实有效 -

here 是由 quick_error

 宏生成的结构示例,
here 是其定义。


0
投票
这对我有用:

macro_rules! make_my_fn { ($name:ident, $t:ty) => { #[doc = concat!("This is documentation for ", stringify!($name), ". # Errors * Makes some Error when bad things happen ")] pub fn $name(&self) -> Result<$t, Error> { // do something to make result Ok(result) } }; }
    
© www.soinside.com 2019 - 2024. All rights reserved.