With "default" constructors, it can be useful to document what the… defaults are. If this is textually defined in the doc and separately defined as a literal or a static / const, the two can get out of sync:
impl Foo {
/// Creates a [Foo] with a `bar` of 3.
fn new() -> Foo { Foo::new_with_bar(5) }
/// Creates a [Foo] with the provided `bar`.
fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
}
It's possible to extract the literal to a const or static and link to that, but then the reader has to go through the indirection to know what the value is, and the const / static has to be pub
or cargo doc
complains and refuses to link to it.
Is there any way to substitute the const value in the docstring instead of linking to it? Or some other method which would avoid the indirection? aka
const DEFAULT_BAR: usize = 5
impl Foo {
/// Creates a [Foo] with a `bar` of ???DEFAULT_BAR???.
fn new() -> Foo { Foo::new_with_bar(DEFAULT_BAR) }
}
should be rendered as:
pub fn new() -> Foo
Creates a Foo with a
bar
of 5.
Although similar, How to embed a Rust macro variable into documentation? doesn't seem to apply here. [doc]
complains about an unexpected token when given a name as a parameter (even a const str) and I don't know if a wrapping macro can force the substitution of a const.
This works in Rust 1.47:
struct Foo { bar: usize }
macro_rules! impl_foo {
($bar_def:expr) => { impl_foo!(@ $bar_def, stringify!($bar_def)); };
(@ $bar_def:expr, $bar_def_str:expr) => {
impl Foo {
/// Creates a [Foo] with a `bar` of
#[doc = $bar_def_str]
///.
fn new() -> Foo { Foo::new_with_bar($bar_def) }
/// Creates a [Foo] with the provided `bar`.
fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
}
}
}
impl_foo!(3);
You can use the paste to avoid the redirection:
use paste::paste;
struct Foo { bar: usize }
macro_rules! impl_foo {
($bar_def:expr) => {
paste! {
impl Foo {
#[doc = "Creates a [Foo] with a `bar` of " $bar_def "."]
fn new() -> Foo { Foo::new_with_bar($bar_def) }
/// Creates a [Foo] with the provided `bar`.
fn new_with_bar(bar: usize) -> Foo { Foo { bar } }
}
}
}
}
impl_foo!(3);
In the future, you'll be able to skip the re-direction in the macro (or the usage of paste!
) by using #![feature(extended_key_value_attributes)]
, as described in vallentin's answer.
See also: