mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 04:29:41 +00:00
add chapter [Docs and Comments]
This commit is contained in:
2
practices/doc-comments/.gitignore
vendored
Normal file
2
practices/doc-comments/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
Cargo.lock
|
7
practices/doc-comments/Cargo.lock
generated
Normal file
7
practices/doc-comments/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doc-comments"
|
||||||
|
version = "0.1.0"
|
8
practices/doc-comments/Cargo.toml
Normal file
8
practices/doc-comments/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "doc-comments"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
36
practices/doc-comments/src/compute.rs
Normal file
36
practices/doc-comments/src/compute.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//! Do some complicated arithmetic that you can't do by yourself
|
||||||
|
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// The function panics if the second argument is zero.
|
||||||
|
///
|
||||||
|
/// ```rust,should_panic
|
||||||
|
/// // panics on division by zero
|
||||||
|
/// doc_comments::compute::div(10, 0);
|
||||||
|
/// ```
|
||||||
|
pub fn div(a: i32, b: i32) -> i32 {
|
||||||
|
if b == 0 {
|
||||||
|
panic!("Divide-by-zero error");
|
||||||
|
}
|
||||||
|
|
||||||
|
a / b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// # fn try_main() -> Result<(), String> {
|
||||||
|
/// let res = doc_comments::compute::try_div(10, 1)?;
|
||||||
|
/// # Ok(()) // returning from try_main
|
||||||
|
/// # }
|
||||||
|
/// # fn main() {
|
||||||
|
/// # try_main().unwrap();
|
||||||
|
/// #
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
|
||||||
|
if b == 0 {
|
||||||
|
Err(String::from("Divide-by-zero"))
|
||||||
|
} else {
|
||||||
|
Ok(a / b)
|
||||||
|
}
|
||||||
|
}
|
54
practices/doc-comments/src/lib.rs
Normal file
54
practices/doc-comments/src/lib.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//! # Doc comments
|
||||||
|
//!
|
||||||
|
//! A library for showing how to use doc comments
|
||||||
|
|
||||||
|
pub mod compute;
|
||||||
|
|
||||||
|
/// Add one to the given value and return a new value
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let arg = 5;
|
||||||
|
/// let answer = doc_comments::add_one(arg);
|
||||||
|
///
|
||||||
|
/// assert_eq!(6, answer);
|
||||||
|
/// ```
|
||||||
|
pub fn add_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Add two to the given value and return a new value
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
let arg = 5;
|
||||||
|
let answer = doc_comments::add_two(arg);
|
||||||
|
|
||||||
|
assert_eq!(7, answer);
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
pub fn add_two(x: i32) -> i32 {
|
||||||
|
x + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Add three to the given value and return a [`Option`] type
|
||||||
|
pub fn add_three(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
mod a {
|
||||||
|
/// Add four to the given value and return a [`Option`] type
|
||||||
|
/// [`crate::MySpecialFormatter`]
|
||||||
|
pub fn add_four(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MySpecialFormatter;
|
||||||
|
|
||||||
|
|
@ -43,8 +43,8 @@
|
|||||||
- [Package and Crate](crate-module/crate.md)
|
- [Package and Crate](crate-module/crate.md)
|
||||||
- [Module](crate-module/module.md)
|
- [Module](crate-module/module.md)
|
||||||
- [Advanced use and pub](crate-module/use-pub.md)
|
- [Advanced use and pub](crate-module/use-pub.md)
|
||||||
- [Comments and Docs TODO](comments-docs.md)
|
- [Comments and Docs](comments-docs.md)
|
||||||
- [Formatted output TODO](formatted-output.md)
|
- [Formatted output](formatted-output.md)
|
||||||
- [Lifetime TODO](lifetime/intro.md)
|
- [Lifetime TODO](lifetime/intro.md)
|
||||||
- [basic](lifetime/basic.md)
|
- [basic](lifetime/basic.md)
|
||||||
- [&'static and T: 'static](lifetime/static.md)
|
- [&'static and T: 'static](lifetime/static.md)
|
||||||
|
@ -1 +1,295 @@
|
|||||||
# Comments and Docs
|
# Comments and Docs
|
||||||
|
Every program requires comments:
|
||||||
|
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
- Regular comments which are ignored by the compiler:
|
||||||
|
- `// Line comment, which goes to the end of the line`
|
||||||
|
- `/* Block comment, which goes to the end of the closing delimiter */`
|
||||||
|
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
// This is an example of a line comment
|
||||||
|
// There are two slashes at the beginning of the line
|
||||||
|
// And nothing written inside these will be read by the compiler
|
||||||
|
|
||||||
|
// println!("Hello, world!");
|
||||||
|
|
||||||
|
// Run it. See? Now try deleting the two slashes, and run it again.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is another type of comment, a block comment. In general,
|
||||||
|
* line comments are the recommended comment style. But
|
||||||
|
* block comments are extremely useful for temporarily disabling
|
||||||
|
* chunks of code. /* Block comments can be /* nested, */ */
|
||||||
|
* so it takes only a few keystrokes to comment out everything
|
||||||
|
* in this main() function. /*/*/* Try it yourself! */*/*/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: The previous column of `*` was entirely for style. There's
|
||||||
|
no actual need for it.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exercises
|
||||||
|
1. 🌟🌟
|
||||||
|
```rust,editable
|
||||||
|
|
||||||
|
/* Make it work, only using comments! */
|
||||||
|
fn main() {
|
||||||
|
todo!();
|
||||||
|
unimplemented!();
|
||||||
|
|
||||||
|
assert_eq!(6, 5 + 3 + 2 + 1 )
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Doc Comments
|
||||||
|
- Doc comments which are parsed into HTML and supported `Markdown`
|
||||||
|
- `/// Generate library docs for the following item`
|
||||||
|
- `//! Generate library docs for the eclosing item`
|
||||||
|
|
||||||
|
Before starting, we need to create a new package for practice: `cargo new --lib doc-comments`.
|
||||||
|
|
||||||
|
|
||||||
|
### Line doc comments `///`
|
||||||
|
Add docs for function `add_one`
|
||||||
|
```rust
|
||||||
|
// in lib.rs
|
||||||
|
|
||||||
|
/// Add one to the given value and return the value
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let arg = 5;
|
||||||
|
/// let answer = my_crate::add_one(arg);
|
||||||
|
///
|
||||||
|
/// assert_eq!(6, answer);
|
||||||
|
/// ```
|
||||||
|
pub fn add_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cargo doc
|
||||||
|
We can use `cargo doc --open` to generate html files and open them in the browser.
|
||||||
|
|
||||||
|
### Block doc comments `/** ... */`
|
||||||
|
Add docs for function `add_two`:
|
||||||
|
```rust
|
||||||
|
/** Add two to the given value and return a new value
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
let arg = 5;
|
||||||
|
let answer = my_crate::add_two(arg);
|
||||||
|
|
||||||
|
assert_eq!(7, answer);
|
||||||
|
|
||||||
|
*/
|
||||||
|
pub fn add_two(x: i32) -> i32 {
|
||||||
|
x + 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Doc comments for crate and module
|
||||||
|
We can also add doc comments for our crates and modules.
|
||||||
|
|
||||||
|
Firstly, let's add some doc comments for our library crate:
|
||||||
|
|
||||||
|
> Note: We mush place crates and module comments at the top of the crate root or module file.
|
||||||
|
```rust
|
||||||
|
//! # Doc comments
|
||||||
|
//!
|
||||||
|
//! A library for showing how to use doc comments
|
||||||
|
|
||||||
|
// in lib.rs
|
||||||
|
pub mod compute;
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use block comments to achieve this:
|
||||||
|
```rust
|
||||||
|
/*! # Doc comments
|
||||||
|
|
||||||
|
A library for showing how to use doc comments */
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, create a new module file `src/compute.rs`, and add following comments to it:
|
||||||
|
```rust
|
||||||
|
//! //! Do some complicated arithmetic that you can't do by yourself
|
||||||
|
|
||||||
|
// in compute.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run `cargo doc --open` and see the results.
|
||||||
|
|
||||||
|
|
||||||
|
### Doc tests
|
||||||
|
The doc comments of `add_one` and `add_tow` contain two example code blocks.
|
||||||
|
|
||||||
|
The examples can not only demonstrate how to use your library, but also running as test with `cargo test` command.
|
||||||
|
|
||||||
|
2. 🌟🌟 But there are errors in the two examples, please fix them, and running with `cargo test` to get following result:
|
||||||
|
```shell
|
||||||
|
running 0 tests
|
||||||
|
|
||||||
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||||
|
|
||||||
|
Doc-tests doc-comments
|
||||||
|
|
||||||
|
running 2 tests
|
||||||
|
test src/lib.rs - add_one (line 11) ... ok
|
||||||
|
test src/lib.rs - add_two (line 26) ... ok
|
||||||
|
|
||||||
|
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.55s
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 🌟🌟 Sometimes we expect an example to be panic, add following code to `src/compute.rs` and make the `cargo test` passed.
|
||||||
|
|
||||||
|
> You can only modify the comments, DON'T modify `fn div`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// in src/compute.rs
|
||||||
|
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// The function panics if the second argument is zero.
|
||||||
|
///
|
||||||
|
/// ```rust,should_panic
|
||||||
|
/// // panics on division by zero
|
||||||
|
/// doc_comments::compute::div(10, 0);
|
||||||
|
/// ```
|
||||||
|
pub fn div(a: i32, b: i32) -> i32 {
|
||||||
|
if b == 0 {
|
||||||
|
panic!("Divide-by-zero error");
|
||||||
|
}
|
||||||
|
|
||||||
|
a / b
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 🌟🌟 Sometimes we want to hide the doc comments, but keep the doc tests.
|
||||||
|
|
||||||
|
Add following code to `src/compute.rs` ,
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// in src/compute.rs
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// # fn try_main() -> Result<(), String> {
|
||||||
|
/// let res = doc_comments::compute::try_div(10, 0)?;
|
||||||
|
/// # Ok(()) // returning from try_main
|
||||||
|
/// # }
|
||||||
|
/// # fn main() {
|
||||||
|
/// # try_main().unwrap();
|
||||||
|
/// #
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
|
||||||
|
if b == 0 {
|
||||||
|
Err(String::from("Divide-by-zero"))
|
||||||
|
} else {
|
||||||
|
Ok(a / b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and modify this code to achieve two goals:
|
||||||
|
|
||||||
|
- The doc comments must not be presented in html files generated by `cargo doc --open`
|
||||||
|
- run the tests, you should see results as below:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
running 0 tests
|
||||||
|
|
||||||
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||||
|
|
||||||
|
Doc-tests doc-comments
|
||||||
|
|
||||||
|
running 4 tests
|
||||||
|
test src/compute.rs - compute::div (line 7) ... ok
|
||||||
|
test src/lib.rs - add_two (line 27) ... ok
|
||||||
|
test src/lib.rs - add_one (line 11) ... ok
|
||||||
|
test src/compute.rs - compute::try_div (line 20) ... ok
|
||||||
|
|
||||||
|
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code navigation
|
||||||
|
Rust provide a very powerful feature for us, that is code navigation in doc comments.
|
||||||
|
|
||||||
|
Add following code to `src/lib.rs`:
|
||||||
|
```rust
|
||||||
|
// in lib.rs
|
||||||
|
|
||||||
|
/// Add one to the given value and return a [`Option`] type
|
||||||
|
pub fn add_three(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 3)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Besides jump into the standard library, you can also jump to another module in the package.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// in lib.rs
|
||||||
|
|
||||||
|
mod a {
|
||||||
|
/// Add four to the given value and return a [`Option`] type
|
||||||
|
/// [`crate::MySpecialFormatter`]
|
||||||
|
pub fn add_four(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MySpecialFormatter;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Doc attributes
|
||||||
|
Below are a few examples of the most common `#[doc]` attributes used with `rustdoc`.
|
||||||
|
|
||||||
|
### `inline`
|
||||||
|
|
||||||
|
Used to inline docs, instead of linking out to separate page.
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use bar::Bar;
|
||||||
|
|
||||||
|
/// bar docs
|
||||||
|
mod bar {
|
||||||
|
/// the docs for Bar
|
||||||
|
pub struct Bar;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `no_inline`
|
||||||
|
|
||||||
|
Used to prevent linking out to separate page or anywhere.
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
// Example from libcore/prelude
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::mem::drop;
|
||||||
|
```
|
||||||
|
|
||||||
|
### `hidden`
|
||||||
|
|
||||||
|
Using this tells `rustdoc` not to include this in documentation:
|
||||||
|
|
||||||
|
```rust,editable,ignore
|
||||||
|
// Example from the futures-rs library
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use self::async_await::*;
|
||||||
|
```
|
||||||
|
|
||||||
|
For documentation, `rustdoc` is widely used by the community. It's what is used to generate the [std library docs](https://doc.rust-lang.org/std/).
|
||||||
|
|
||||||
|
|
||||||
|
### Full Code
|
||||||
|
The full code of package `doc-comments` is [here](https://github.com/sunface/rust-by-practice/tree/master/practices/doc-comments).
|
||||||
|
Reference in New Issue
Block a user