summary refs log tree commit diff
path: root/Rust.md
blob: aa1ad6c1f8668c6edc08a17665fa906d685d5fbf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Whitespace

## Indentation

Use two-space indentation for any form of block nesting:

```
fn command_str(c: char, state: &mut RPState) -> Result<(), Exit> {
  if c != ')' {
    state.wip_str.push(c);
  }
}
```


## Line wrapping

To the greatest extent possible, never have a line wider than 80 characters.

If you can, break long statements into shorter ones. If you can't, wrap them
onto multiple lines. There are two ways to do this.

EITHER indent by four spaces with respect to the parent line:

```
              return Err(err_msg(format!(
                  "Stack depth should be at least: {}", d)));
```

OR indent to a depth that lines up with the start of the sub-expression you're
breaking in:

```
    state.num += to_decimal(c.to_digit(10).unwrap())
                 * state.decimal_offset;
```

When doing the latter, put any operator or other punctuation that's needed
at the beginning of the continuation line, not the end of the first line.

In very rare situations when the structure of code is some sort of tabular
list, it may make sense to break with these patterns and indent in ways that
make the tabular structure evident.

Regardless of which type of continuation line you choose, if the line you're
wrapping is also the start of a block, put the curly brace or similar
block-opening character on a line by itself:

```
  } else if let 'p' | 'n' | 'q' | 'l' | 's' | 'v' | 'x' | 'd' | ',' | 'c'
              | '!' | '?' = c
  {
```

Notice that this example also happens to demonstrate the tabular-structure
approach.


## Indent or wrap?

Because Rust does the thing where control flow constructs and compound
literals are ordinary expressions that can be used anywhere, you may sometimes
have to apply some judgement about whether to treat a piece of code as a block
or a continued line.

In this example, an array literal is being treated as a code block:

```
  let kvs = [
    ("F->C", "1! 32- 5 9/*"),
    ("C->F", "1! 9 5/* 32+"),
    ("C->K", "1! 273+"),
    ("K->C", "1! 273-"),
    ("Km->mi", "1! 1.609344/"),
    ("mi->Km", "1! 1.609344*"),
  ].map(|kv: (&str, &str)| (String::from(kv.0), Value::Str(kv.1.into())));
```


## Vertical space at the top level

In general, put two blank lines between function or type definitions that are
unrelated to each other.

If you wish to express that two top-level constructs are closely related, such
as a trait implementation definition or utility function immediately following
a type definition that it pertains to, use a single blank line instead of two.

Constant definitions may directly abut each other - with no intervening
lines - if you so wish.

Put all `use` and `mod` declarations at the top of the file, with two blank
lines separating this section from everything else the file defines.