Skip to content

Commit ec3d345

Browse files
committed
Formatting guidelines
This RFC defines an official Rust style guide. The style is a specification for the default behaviour of [Rustfmt](https://github.com/rust-lang-nursery/rustfmt), is required for official Rust projects (including the compiler and standard libraries), and is recommended for all Rust projects. The style guide in this RFC only covers the formatting of code, it does not have any recommendations about how to write idiomatic or high quality Rust code.
1 parent bae79fc commit ec3d345

File tree

9 files changed

+2013
-0
lines changed

9 files changed

+2013
-0
lines changed

style-guide/README.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Rust Style Guide
2+
3+
## Motivation - why use a formatting tool?
4+
5+
Formatting code is a mostly mechanical task which takes both time and mental
6+
effort. By using an automatic formatting tool, a programmer is relieved of
7+
this task and can concentrate on more important things.
8+
9+
Furthermore, by sticking to an established style guide (such as this one),
10+
programmers don't need to formulate ad hoc style rules, nor do they need to
11+
debate with other programmers what style rules should be used, saving time,
12+
communication overhead, and mental energy.
13+
14+
Humans comprehend information through pattern matching. By ensuring that all
15+
Rust code has similar formatting, less mental effort is required to comprehend a
16+
new project, lowering the bar to entry for new developers.
17+
18+
Thus, there are productivity benefits to using a formatting tool (such as
19+
rustfmt), and even larger benefits by using a community-consistent formatting,
20+
typically by using a formatting tool's default settings.
21+
22+
23+
## Formatting conventions
24+
25+
### Indentation and line width
26+
27+
Use spaces, not tabs. Each level of indentation must be four spaces. The maximum
28+
width for a line is 100 characters. A tool should be configurable for all three
29+
of these variables.
30+
31+
32+
### Blank lines
33+
34+
Separate items and statements by either zero or one blank lines (i.e., one or
35+
two newlines). E.g,
36+
37+
```rust
38+
fn foo() {
39+
let x = ...;
40+
41+
let y = ...;
42+
let z = ...;
43+
}
44+
45+
fn bar() {}
46+
fn baz() {}
47+
```
48+
49+
Formatting tools should make the bounds on blank lines configurable: there
50+
should be separate minimum and maximum numbers of newlines between both
51+
statements and (top-level) items (i.e., four options). As described above, the
52+
defaults for both statements and items should be minimum: 1, maximum: 2.
53+
54+
55+
### [Module-level items](items.md)
56+
### [Statements](statements.md)
57+
### [Expressions](expressions.md)
58+
### [Types](types.md)
59+
60+
61+
### Comments
62+
63+
The following guidelines are recommendations only, a mechanical formatter should
64+
not change comments except to move them within a file. To be clear this means
65+
changing the whitespace before a line comment or the whitespace before or after
66+
a block comment.
67+
68+
Prefer line comments (`//`) to block comments (`/* ... */`).
69+
70+
When using line comments there should be a single space after the opening sigil.
71+
72+
When using single-line block comments there should be a single space after the
73+
opening sigil and before the closing sigil. Multi-line block comments should
74+
have a newline after the opening sigil and before the closing sigil.
75+
76+
Prefer to put a comment on its own line. Where a comment follows code, there
77+
should be a single space before it. Where a block comment is inline, there
78+
should be surrounding whitespace as if it were an identifier or keyword. There
79+
should be no trailing whitespace after a comment. Examples:
80+
81+
```rust
82+
// A comment on an item.
83+
struct Foo { ... }
84+
85+
fn foo() {} // A comment after an item.
86+
87+
pub fn foo(/* a comment before an argument */ x: T) {...}
88+
```
89+
90+
Comments should usually be complete sentences. Start with a capital letter, end
91+
with a period (`.`). An inline block comment may be treated as a note without
92+
punctuation.
93+
94+
Source lines which are entirely a comment should be limited to 80 characters
95+
in length (including comment sigils, but excluding indentation) or the maximum
96+
width of the line (including comment sigils and indentation), whichever is
97+
smaller:
98+
99+
```rust
100+
// This comment goes up to the ................................. 80 char margin.
101+
102+
{
103+
// This comment is .............................................. 80 chars wide.
104+
}
105+
106+
{
107+
{
108+
{
109+
{
110+
{
111+
{
112+
// This comment is limited by the ......................... 100 char margin.
113+
}
114+
}
115+
}
116+
}
117+
}
118+
}
119+
```
120+
121+
#### Doc comments
122+
123+
Prefer line comments (`///`) to block comments (`//* ... */`).
124+
125+
Prefer outer doc comments (`///` or `//*`), only use inner doc comments (`//!`
126+
and `//*!`) to write module-level or crate-level documentation.
127+
128+
Doc comments should come before attributes.
129+
130+
### Attributes
131+
132+
Put each attribute on its own line, indented to the indentation of its item.
133+
In the case of inner attributes (`#!`), indent it to the inner indentation (the
134+
indentation of the item + 1). Prefer outer attributes, where possible.
135+
136+
For attributes with argument lists, format like functions.
137+
138+
```rust
139+
#[repr(C)]
140+
#[foo(foo, bar)]
141+
struct CRepr {
142+
#![repr(C)]
143+
x: f32,
144+
y: f32,
145+
}
146+
```
147+
148+
For attributes with an equal sign, there should be a single space before and
149+
after the `=`, e.g., `#[foo = 42]`.
150+
151+
There must only be a single `derive` attribute. Note for tool authors: if
152+
combining multiple `derive` attributes into a single attribute, the ordering of
153+
the derived names should be preserved. E.g., `#[derive(bar)] #[derive(foo)]
154+
struct Baz;` should be formatted to `#[derive(bar, foo)] struct Baz;`.
155+
156+
### *small* items
157+
158+
In many places in this guide we specify that a formatter may format an item
159+
differently if it is *small*, for example struct literals:
160+
161+
```rust
162+
// Normal formatting
163+
Foo {
164+
f1: an_expression,
165+
f2: another_expression(),
166+
}
167+
168+
// *small* formatting
169+
Foo { f1, f2 }
170+
```
171+
172+
We leave it to individual tools to decide on exactly what *small* means. In
173+
particular, tools are free to use different definitions in different
174+
circumstances.
175+
176+
Some suitable heuristics are the size of the item (in characters) or the
177+
complexity of an item (for example, that all components must be simple names,
178+
not more complex sub-expressions). For more discussion on suitable heuristics,
179+
see the discussion on [this issue](https://github.com/rust-lang-nursery/fmt-rfcs/issues/47).
180+
181+
Tools should give the user an option to ignore such heuristics and always use
182+
the normal formatting.
183+
184+
185+
## [Non-formatting conventions](advice.md)
186+
187+
## [Cargo.toml conventions](cargo.md)

style-guide/advice.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Other style advice
2+
3+
## Expressions
4+
5+
Prefer to use Rust's expression oriented nature where possible;
6+
7+
```rust
8+
// use
9+
let x = if y { 1 } else { 0 };
10+
// not
11+
let x;
12+
if y {
13+
x = 1;
14+
} else {
15+
x = 0;
16+
}
17+
```
18+
19+
## Names
20+
21+
* Types shall be `PascalCase`,
22+
* Enum variants shall be `PascalCase`,
23+
* Struct fields shall be `snake_case`,
24+
* Function and method names shall be `snake_case`,
25+
* Local variables shall be `snake_case`,
26+
* Macro names shall be `snake_case`,
27+
* Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`.
28+
* When a name is forbidden because it is a reserved word (e.g., `crate`), use a
29+
trailing underscore to make the name legal (e.g., `crate_`).
30+
31+
### Modules
32+
33+
Avoid `#[path]` annotations where possible.

style-guide/cargo.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Cargo.toml conventions
2+
3+
## Formatting conventions
4+
5+
Use the same line width and indentation as Rust code.
6+
7+
Put a blank line between the last key-value pair in a section and the header of
8+
the next section. Do not place a blank line between section headers and the
9+
key-value pairs in that section, or between key-value pairs in a section.
10+
11+
Sort key names alphabetically within each section, with the exception of the
12+
`[package]` section. Put the `[package]` section at the top of the file; put
13+
the `name` and `version` keys in that order at the top of that section,
14+
followed by the remaining keys other than `description` in alphabetical order,
15+
followed by the `description` at the end of that section.
16+
17+
Don't use quotes around any standard key names; use bare keys. Only use quoted
18+
keys for non-standard keys whose names require them, and avoid introducing such
19+
key names when possible. See the [TOML
20+
specification](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md#table)
21+
for details.
22+
23+
Put a single space both before and after the `=` between a key and value. Do
24+
not indent any key names; start all key names at the start of a line.
25+
26+
Use multi-line strings (rather than newline escape sequences) for any string
27+
values that include multiple lines, such as the crate description.
28+
29+
For array values, such as a list of authors, put the entire list on the same
30+
line as the key, if it fits. Otherwise, use block indentation: put a newline
31+
after the opening square bracket, indent each item by one indentation level,
32+
put a comma after each item (including the last), and put the closing square
33+
bracket at the start of a line by itself after the last item.
34+
35+
```rust
36+
authors = [
37+
"A Uthor <a.uthor@example.org>",
38+
"Another Author <author@example.net>",
39+
]
40+
```
41+
42+
For table values, such as a crate dependency with a path, write the entire
43+
table using curly braces and commas on the same line as the key if it fits. If
44+
the entire table does not fit on the same line as the key, separate it out into
45+
a separate section with key-value pairs:
46+
47+
```toml
48+
[dependencies]
49+
crate1 = { path = "crate1", version = "1.2.3" }
50+
51+
[dependencies.extremely_long_crate_name_goes_here]
52+
path = "extremely_long_path_name_goes_right_here"
53+
version = "4.5.6"
54+
```
55+
56+
## Metadata conventions
57+
58+
The authors list should consist of strings that each contain an author name
59+
followed by an email address in angle brackets: `Full Name <email@address>`.
60+
It should not contain bare email addresses, or names without email addresses.
61+
(The authors list may also include a mailing list address without an associated
62+
name.)
63+
64+
The license field must contain a valid [SPDX
65+
expression](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60),
66+
using valid [SPDX license names](https://spdx.org/licenses/). (As an exception,
67+
by widespread convention, the license field may use `/` in place of ` OR `; for
68+
example, `MIT/Apache-2.0`.)
69+
70+
The homepage field, if present, must consist of a single URL, including the
71+
scheme (e.g. `https://example.org/`, not just `example.org`.)
72+
73+
Within the description field, wrap text at 78 columns. Don't start the
74+
description field with the name of the crate (e.g. "cratename is a ..."); just
75+
describe the crate itself. If providing a multi-sentence description, the first
76+
sentence should go on a line by itself and summarize the crate, like the
77+
subject of an email or commit message; subsequent sentences can then describe
78+
the crate in more detail.

0 commit comments

Comments
 (0)