How to document feature-gated derived traits? - rust

I understand that I can use the cfg_attr attribute to conditionally derive Trait implementations for types. For example, A struct MyStruct which always implements Clone, Copy, and Debug, but which implements PartialEq if and only if the my-feature feature is enabled, can be defined as follows:
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "my-feature", derive(PartialEq)]
struct MyStruct;
But is it possible to make the generated documentation reflect this? I would like the rustdoc-generated documentation to state that PartialEq is implemented for MyStruct if and only if the my-feature feature is enabled.
So far, I have only accomplished two outcomes, neither of which I want:
If I compile the docs with the my-feature feature enabled, the generated documentation just says that MyStruct implements PartialEq, with no mention of feature gating
If I compile the docs without the my-feautre feature enabled, generated documentation does not indicate that PartialEq is or can be implemented for MyStruct.

Related

Where is the implementation of Display trait for &str

I know that str implements the trait Display. However, It is said that &str also implements this trait.
I wanna inspect the implementation detail of Display trait for &str, but I searched the resource code base of Rust and didn't find it. It doesn't exist in the std::str or the std::fmt::Display crates.
Maybe I had miss something I didn't realize. Can anyone give me some clue about where to find it?
First, str implements Display, i.e.: impl Display for str.
Second, there is a blanket implementation that implements Display for every reference type whose referent type also implements Display, i.e., impl<'_, T> Display for &'_ T where T: Display + ?Sized
Therefore, &str implements Display because its referent type, str, also does.
It is not implemented directly for &str. Rather, there is a blanket implementation impl<T: ?Sized + Display> Display for &'_ T.

Will GATs allow HKTs for non-associated generic parameters?

When looking into Higher-kinded types (HKTs), Generic associated types (GATs) constantly pop up as "the solution". They allow you to express things like this (which I think is really cool):
trait Foo {
type Bar<T>;
fn process<T>(&mut self, ctx: Self::Bar<T>);
}
I'm really excited about GATs being close to landing, but from what I understand it only enables HKTs for traits that use associated types. Or is there a way to express something like this too? (And if not, is there a feature flag or working issue for it?)
trait Foo<for<T> Bar> {
fn process<T>(&mut self, ctx: Self::Bar<T>);
}

Why does implementing Display for a struct add the ability to call to_string() on it? [duplicate]

I have a type Foo that I want to be able to display to the end user as a string, is it more idiomatic to do this by implementing Display or by implementing ToString?
If Display is the way to go, how would I actually end up with a String? I suspect I need to make use of write!, but I'm not entirely sure how.
You should not implement ToString manually. The ToString trait is already implemented for all types which implement fmt::Display:
impl<T> ToString for T
where
T: Display + ?Sized,
{ /* ... */ }
If you implement Display, to_string() will be available on your type automatically.
fmt::Display is intended to be implemented manually for those select few types which should be displayed to the user, while fmt::Debug is expected to be implemented for all types in such a way that represents their internals most nicely (for most types this means that they should have #[derive(Debug)] on them).
In order to obtain the string representation of fmt::Debug output you need to use format!("{:?}", value), with {:?} being a placeholder for types which implement fmt::Debug.
RFC 565 defines guidelines for when to use fmt::Debug and fmt::Display.

Conditionally derive based on feature flag [duplicate]

This question already has an answer here:
Is it possible to conditionally enable an attribute like `derive`?
(1 answer)
Closed 2 years ago.
I want to add a feature to my crate that will optionally make certain structs serializable, and in particular, I want to use Serde's custom derive macros. The Serde dependencies are optional and extern crate declarations are conditionally included behind the feature. Consider the following:
#[derive(Eq, PartialEq, Serialize)]
struct MyStruct {
a: u8,
b: u8
}
With the feature flag enabled, it all works fine. With it disabled, I get this warning:
error: '#[derive]' for custom traits is not stable enough for use. It is deprecated and will be removed in v1.15 (see issue #29644)
Is there a way to conditionally include derived traits? I'm using Rust 1.15 stable.
Should I submit an issue for the error message? It seems misleading.
Like many other pieces of feature-based conditional compilation, use cfg_attr:
#[cfg_attr(feature = "example", derive(Debug))]
struct Foo;
fn main() {
println!("{:?}", Foo);
}
With this, cargo run will fail to compile as Debug is not implemented for Foo, but cargo run --features example will compile and run successfully.

How to link to other fns/structs/enums/traits in rustdoc?

I'm building a Rust library and want to give it some polish. In the rustdoc, I'd sometimes like to link to other parts of the library within the docs, e.g. fns, traits or structs. What is the official syntax for this?
As of Rust 1.48, you can now rely on RFC 1946. This adds the concept of intra-documentation links. This allows using Rust paths as the URL of a link:
[Iterator](std::iter::Iterator)
[Iterator][iter], and somewhere else in the document: [iter]: std::iter::Iterator
[Iterator], and somewhere else in the document: [Iterator]: std::iter::Iterator
The RFC also introduces "Implied Shortcut Reference Links". This allows leaving out the link reference, which is then inferred automatically.
[std::iter::Iterator], without having a link reference definition for Iterator anywhere else in the document
[`std::iter::Iterator`], without having a link reference definition for Iterator anywhere else in the document (same as previous style but with back ticks to format link as inline code)
As a concrete example, this source code:
//! Check out [ExampleStruct], especially [this
//! method](ExampleStruct::foo), but [the trait method][trait] is also
//! cool. There is also [an enum variant you can
//! use](nested::ExampleEnum::Beta).
//!
//! [trait]: ExampleTrait::bar
pub struct ExampleStruct;
impl ExampleStruct {
pub fn foo(&self) {}
}
pub trait ExampleTrait {
fn bar();
}
pub mod nested {
pub enum ExampleEnum {
Alpha,
Beta,
}
}
Produces this documentation:
Specifically, this HTML is generated:
<p>Check out ExampleStruct, especially this method, but the trait method is also cool. There is also an enum variant you can use.</p>
As of Rust 1.48, Rustdoc now supports direct intra-doc links.
Pre Rust 1.48:
Rustdoc seems to generate mostly deterministic filenames for constituent elements of a crate. Therefore if you have an enum named Complex you can generally link to it using:
[Complex](enum.Complex.html)
Similarly a struct called Point would look like:
[Point](struct.Point.html)
This should carry over to most definitions (fn, trait, and so on).
For referencing elements of a crate at different nesting levels, you can use relative paths (where each module is its own folder):
[Point](../model/struct.Point.html)
or use absolute paths:
[Point](/crate_name/model/struct.Point.html)
More of these "conventions", including anchors for specific fields, etc., can be deduced if one builds docs (cargo doc --no-deps --open) and navigates to the field or item they want and takes note of the URL. Remember that only pub items are published to docs.
If one wants to link some specific part of a struct e.g., a method named foo in the same struct (using stable rust, not nightly)
[foo](#method.foo)
or if it is in another struct
[foo](struct.OtherStruct.html#method.foo)
In Rust 1.49 nightly it works (1.48 stable not released yet):
[super::structs::WebApiResponse]
[mycrate::structs::WebApiResponse]
etc.
Read here
Since the documentation is written in Markdown, just use the Markdown syntax for Hyperlinks; i.e.
[anchor text](URL)
Also, take a look at this: https://doc.rust-lang.org/book/documentation.html

Resources