]>
Commit | Line | Data |
---|---|---|
60c5eb7d XL |
1 | # How to write documentation |
2 | ||
29967ef6 XL |
3 | Good documentation is not natural. There are opposing goals that make writing |
4 | good documentation difficult. It requires expertise in the subject but also | |
5 | writing to a novice perspective. Documentation therefore often glazes over | |
6 | implementation detail, or leaves readers with unanswered questions. | |
7 | ||
8 | There are a few tenets to Rust documentation that can help guide anyone through | |
9 | the process of documenting libraries so that everyone has an ample opportunity | |
6a06907d | 10 | to use the code. |
29967ef6 | 11 | |
60c5eb7d | 12 | This chapter covers not only how to write documentation but specifically |
29967ef6 | 13 | how to write **good** documentation. It is important to be as clear |
60c5eb7d XL |
14 | as you can, and as complete as possible. As a rule of thumb: the more |
15 | documentation you write for your crate the better. If an item is public | |
16 | then it should be documented. | |
17 | ||
29967ef6 XL |
18 | ## Getting Started |
19 | ||
20 | Documenting a crate should begin with front-page documentation. As an | |
21 | example, the [`hashbrown`] crate level documentation summarizes the role of | |
6a06907d XL |
22 | the crate, provides links to explain technical details, and explains why you |
23 | would want to use the crate. | |
29967ef6 | 24 | |
6a06907d | 25 | After introducing the crate, it is important that the front-page gives |
29967ef6 XL |
26 | an example of how to use the crate in a real world setting. Stick to the |
27 | library's role in the example, but do so without shortcuts to benefit users who | |
6a06907d | 28 | may copy and paste the example to get started. |
29967ef6 XL |
29 | |
30 | [`futures`] uses inline comments to explain line by line | |
6a06907d | 31 | the complexities of using a [`Future`], because a person's first exposure to |
29967ef6 XL |
32 | rust's [`Future`] may be this example. |
33 | ||
6a06907d | 34 | The [`backtrace`] documentation walks through the whole process, explaining |
29967ef6 | 35 | changes made to the `Cargo.toml` file, passing command line arguments to the |
6a06907d | 36 | compiler, and shows a quick example of backtrace in the wild. |
29967ef6 XL |
37 | |
38 | Finally, the front-page can eventually become a comprehensive reference | |
39 | how to use a crate, like [`regex`]. In this front page, all | |
6a06907d | 40 | requirements are outlined, the edge cases shown, and practical examples |
29967ef6 XL |
41 | provided. The front page goes on to show how to use regular expressions |
42 | then concludes with crate features. | |
43 | ||
44 | Don't worry about comparing your crate, which is just beginning, to other more | |
45 | developed crates. To get the documentation to something more polished, start | |
6a06907d | 46 | incrementally and put in an introduction, example, and features. Rome was not |
29967ef6 XL |
47 | built in a day! |
48 | ||
49 | The first lines within the `lib.rs` will compose the front-page, and they | |
50 | use a different convention than the rest of the rustdocs. Lines should | |
51 | start with `//!` which indicate module-level or crate-level documentation. | |
52 | Here's a quick example of the difference: | |
53 | ||
6a06907d | 54 | ```rust,no_run |
29967ef6 XL |
55 | //! Fast and easy queue abstraction. |
56 | //! | |
57 | //! Provides an abstraction over a queue. When the abstraction is used | |
58 | //! there are these advantages: | |
59 | //! - Fast | |
60 | //! - [`Easy`] | |
61 | //! | |
62 | //! [`Easy`]: http://thatwaseasy.example.com | |
63 | ||
64 | /// This module makes it easy. | |
65 | pub mod easy { | |
66 | ||
6a06907d XL |
67 | /// Use the abstraction function to do this specific thing. |
68 | pub fn abstraction() {} | |
29967ef6 XL |
69 | |
70 | } | |
71 | ``` | |
72 | ||
6a06907d | 73 | Ideally, this first line of documentation is a sentence without highly |
29967ef6 XL |
74 | technical details, but with a good description of where this crate fits |
75 | within the rust ecosystem. Users should know whether this crate meets their use | |
76 | case after reading this line. | |
77 | ||
78 | ## Documenting components | |
79 | ||
80 | Whether it is modules, structs, functions, or macros: the public | |
81 | API of all code should have documentation. Rarely does anyone | |
82 | complain about too much documentation! | |
60c5eb7d XL |
83 | |
84 | It is recommended that each item's documentation follows this basic structure: | |
85 | ||
86 | ```text | |
87 | [short sentence explaining what it is] | |
88 | ||
89 | [more detailed explanation] | |
90 | ||
91 | [at least one code example that users can copy/paste to try it] | |
92 | ||
93 | [even more advanced explanations if necessary] | |
94 | ``` | |
95 | ||
96 | This basic structure should be straightforward to follow when writing your | |
29967ef6 | 97 | documentation; while you might think that a code example is trivial, |
6a06907d | 98 | the examples are really important because they can help users understand |
29967ef6 | 99 | what an item is, how it is used, and for what purpose it exists. |
60c5eb7d XL |
100 | |
101 | Let's see an example coming from the [standard library] by taking a look at the | |
102 | [`std::env::args()`][env::args] function: | |
103 | ||
6a06907d | 104 | ``````markdown |
60c5eb7d XL |
105 | Returns the arguments which this program was started with (normally passed |
106 | via the command line). | |
107 | ||
108 | The first element is traditionally the path of the executable, but it can be | |
109 | set to arbitrary text, and may not even exist. This means this property should | |
110 | not be relied upon for security purposes. | |
111 | ||
112 | On Unix systems shell usually expands unquoted arguments with glob patterns | |
113 | (such as `*` and `?`). On Windows this is not done, and such arguments are | |
114 | passed as-is. | |
115 | ||
116 | # Panics | |
117 | ||
118 | The returned iterator will panic during iteration if any argument to the | |
119 | process is not valid unicode. If this is not desired, | |
120 | use the [`args_os`] function instead. | |
121 | ||
122 | # Examples | |
123 | ||
124 | ``` | |
125 | use std::env; | |
126 | ||
127 | // Prints each argument on a separate line | |
128 | for argument in env::args() { | |
129 | println!("{}", argument); | |
130 | } | |
131 | ``` | |
132 | ||
133 | [`args_os`]: ./fn.args_os.html | |
134 | `````` | |
135 | ||
6a06907d | 136 | Everything before the first empty line will be reused to describe the component |
29967ef6 | 137 | in searches and module overviews. For example, the function `std::env::args()` |
6a06907d | 138 | above will be shown on the [`std::env`] module documentation. It is good |
29967ef6 XL |
139 | practice to keep the summary to one line: concise writing is a goal of good |
140 | documentation. | |
141 | ||
142 | Because the type system does a good job of defining what types a function | |
143 | passes and returns, there is no benefit of explicitly writing it | |
144 | into the documentation, especially since `rustdoc` adds hyper links to all types in the function signature. | |
145 | ||
146 | In the example above, a 'Panics' section explains when the code might abruptly exit, | |
147 | which can help the reader prevent reaching a panic. A panic section is recommended | |
148 | every time edge cases in your code can be reached if known. | |
149 | ||
60c5eb7d XL |
150 | As you can see, it follows the structure detailed above: it starts with a short |
151 | sentence explaining what the functions does, then it provides more information | |
152 | and finally provides a code example. | |
153 | ||
154 | ## Markdown | |
155 | ||
6a06907d XL |
156 | `rustdoc` uses the [CommonMark Markdown specification]. You might be |
157 | interested in taking a look at their website to see what's possible: | |
158 | ||
159 | - [CommonMark quick reference] | |
29967ef6 | 160 | - [current spec] |
60c5eb7d | 161 | |
5869c6ff XL |
162 | In addition to the standard CommonMark syntax, `rustdoc` supports several |
163 | extensions: | |
164 | ||
165 | ### Strikethrough | |
166 | ||
167 | Text may be rendered with a horizontal line through the center by wrapping the | |
168 | text with two tilde characters on each side: | |
169 | ||
170 | ```text | |
171 | An example of ~~strikethrough text~~. | |
172 | ``` | |
173 | ||
174 | This example will render as: | |
175 | ||
176 | > An example of ~~strikethrough text~~. | |
177 | ||
178 | This follows the [GitHub Strikethrough extension][strikethrough]. | |
179 | ||
180 | ### Footnotes | |
181 | ||
182 | A footnote generates a small numbered link in the text which when clicked | |
183 | takes the reader to the footnote text at the bottom of the item. The footnote | |
184 | label is written similarly to a link reference with a caret at the front. The | |
185 | footnote text is written like a link reference definition, with the text | |
186 | following the label. Example: | |
187 | ||
188 | ```text | |
189 | This is an example of a footnote[^note]. | |
190 | ||
191 | [^note]: This text is the contents of the footnote, which will be rendered | |
192 | towards the bottom. | |
193 | ``` | |
194 | ||
195 | This example will render as: | |
196 | ||
197 | > This is an example of a footnote[^note]. | |
198 | > | |
199 | > [^note]: This text is the contents of the footnote, which will be rendered | |
200 | > towards the bottom. | |
201 | ||
202 | The footnotes are automatically numbered based on the order the footnotes are | |
203 | written. | |
204 | ||
205 | ### Tables | |
206 | ||
207 | Tables can be written using pipes and dashes to draw the rows and columns of | |
208 | the table. These will be translated to HTML table matching the shape. Example: | |
209 | ||
210 | ```text | |
211 | | Header1 | Header2 | | |
212 | |---------|---------| | |
213 | | abc | def | | |
214 | ``` | |
215 | ||
216 | This example will render similarly to this: | |
217 | ||
218 | > | Header1 | Header2 | | |
219 | > |---------|---------| | |
220 | > | abc | def | | |
221 | ||
222 | See the specification for the [GitHub Tables extension][tables] for more | |
223 | details on the exact syntax supported. | |
60c5eb7d | 224 | |
6a06907d XL |
225 | ### Task lists |
226 | ||
227 | Task lists can be used as a checklist of items that have been completed. | |
228 | Example: | |
229 | ||
230 | ```md | |
231 | - [x] Complete task | |
17df50a5 | 232 | - [ ] Incomplete task |
6a06907d XL |
233 | ``` |
234 | ||
17df50a5 | 235 | This will render as: |
6a06907d | 236 | |
17df50a5 XL |
237 | > - [x] Complete task |
238 | > - [ ] Incomplete task | |
6a06907d XL |
239 | |
240 | See the specification for the [task list extension] for more details. | |
241 | ||
242 | ### Smart punctuation | |
243 | ||
244 | Some ASCII punctuation sequences will be automatically turned into fancy Unicode | |
245 | characters: | |
246 | ||
247 | | ASCII sequence | Unicode | | |
248 | |----------------|---------| | |
249 | | `--` | – | | |
250 | | `---` | — | | |
251 | | `...` | … | | |
252 | | `"` | “ or ”, depending on context | | |
253 | | `'` | ‘ or ’, depending on context | | |
254 | ||
255 | So, no need to manually enter those Unicode characters! | |
256 | ||
29967ef6 | 257 | [`backtrace`]: https://docs.rs/backtrace/0.3.50/backtrace/ |
60c5eb7d | 258 | [commonmark markdown specification]: https://commonmark.org/ |
29967ef6 XL |
259 | [commonmark quick reference]: https://commonmark.org/help/ |
260 | [env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html | |
6a06907d | 261 | [`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html |
29967ef6 XL |
262 | [`futures`]: https://docs.rs/futures/0.3.5/futures/ |
263 | [`hashbrown`]: https://docs.rs/hashbrown/0.8.2/hashbrown/ | |
264 | [`regex`]: https://docs.rs/regex/1.3.9/regex/ | |
265 | [standard library]: https://doc.rust-lang.org/stable/std/index.html | |
266 | [current spec]: https://spec.commonmark.org/current/ | |
267 | [`std::env`]: https://doc.rust-lang.org/stable/std/env/index.html#functions | |
5869c6ff XL |
268 | [strikethrough]: https://github.github.com/gfm/#strikethrough-extension- |
269 | [tables]: https://github.github.com/gfm/#tables-extension- | |
6a06907d | 270 | [task list extension]: https://github.github.com/gfm/#task-list-items-extension- |