Skip to content
This repository was archived by the owner on Oct 9, 2018. It is now read-only.

Commit d588175

Browse files
committed
Merge pull request #5 from nathantypanski/modules
features/modules: Expand modules section
2 parents 0f66d0d + 4c20877 commit d588175

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

features/modules.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,129 @@
44
55
> We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
66
> around modules.
7+
8+
#### Naming conventions
9+
> **[OPEN]**
10+
> - Anything else?
11+
> - Are there cases where *not* separating words with underscores is OK,
12+
> or should this be a hard rule?
13+
14+
- Module names should contain only lowercae letters and underscores.
15+
For example, use `std::io::timer`, not `Std::IO::Timer`.
16+
- Multiple words should be separated by underscores.
17+
Use `std::local_data`, not `std::localData` or `std::localdata`.
18+
19+
#### Headers
20+
> **[OPEN]** Is this header organization suggestion valid?
21+
22+
Organize module headers as follows:
23+
1. [Imports](../style/imports.md).
24+
1. `mod` declarations.
25+
1. `pub mod` declarations.
26+
27+
#### Avoid `path` directives
28+
> **[OPEN]** This is hardly ever seen in the Rust codebase (only 4 uses, all in
29+
> `libsyntax`) and seems like overall a bad idea.
30+
31+
Avoid using `#[path="..."]` directives except where it is *absolutely*
32+
necessary.
33+
34+
### Use the module hirearchy to organize APIs into coherent sections
35+
> **[OPEN]**
36+
37+
The module hirearchy defines both the public and internal API of your module.
38+
Breaking related functionality into submodules makes it understandable to both
39+
users and contributors to the module.
40+
41+
#### Place modules in separate files
42+
> **[OPEN]**
43+
> - "<100 lines" is completely arbitrary, but it's a clearer recommendation
44+
> than "~1 page" or similar suggestions that vary by screen size, etc.
45+
46+
For all except very short modules (<100 lines) and [tests](../testing/README.md),
47+
place the module `foo` in a separate file: either `foo.rs` or `foo/mod.rs`,
48+
depending on your needs, rather than declaring it inline like
49+
50+
```rust
51+
pub mod foo {
52+
pub fn bar() { println!("..."); }
53+
/* ... */
54+
}
55+
```
56+
57+
#### Use folders to organize submodules
58+
> **[OPEN]**
59+
60+
For modules that themselves have submodules, place the module in a separate
61+
folder (e.g., `bar/mod.rs` for a module `bar`) rather than the same directory.
62+
63+
Note the structure of
64+
[`std::io`](http://doc.rust-lang.org/std/io/). Many of the submodules lack
65+
children, like
66+
[`io::fs`](http://doc.rust-lang.org/std/io/fs/)
67+
and
68+
[`io::stdio`](http://doc.rust-lang.org/std/io/stdio/).
69+
On the other hand,
70+
[`io::net`](http://doc.rust-lang.org/std/io/net/)
71+
contains submodules, so it lives in a separate folder:
72+
73+
```
74+
io/mod.rs
75+
io/extensions.rs
76+
io/fs.rs
77+
io/net/mod.rs
78+
io/net/addrinfo.rs
79+
io/net/ip.rs
80+
io/net/tcp.rs
81+
io/net/udp.rs
82+
io/net/unix.rs
83+
io/pipe.rs
84+
...
85+
```
86+
87+
While it is possible to define all of `io` within a single folder, mirroring
88+
the module hirearchy in the directory structure makes submodules of `io::net`
89+
easier to find.
90+
91+
#### Top-level definitions
92+
> **[OPEN]**
93+
94+
Define or [reexport](http://doc.rust-lang.org/std/io/#reexports) commonly used
95+
definitions at the top level of your module.
96+
97+
Functionality that is related to the module itself should be defined in
98+
`mod.rs`, while functionality specific to a submodule should live in its
99+
related submodule and be reexported elsewhere.
100+
101+
For example,
102+
[`IoError`](http://doc.rust-lang.org/std/io/struct.IoError.html)
103+
is defined in `io/mod.rs`, since it pertains to the entirety of the submodule,
104+
while
105+
[`TcpStream`](http://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
106+
is defined in `io/net/tcp.rs` and reexported in the `io` module.
107+
108+
### Use internal module hirearchies for hiding implementations
109+
> **[OPEN]**
110+
> - Referencing internal modules from the standard library is subject to
111+
> becoming outdated.
112+
113+
Internal module hirearchies (including private submodules) may be used to
114+
hide implementation details that are not part of the module's API.
115+
116+
For example, in [`std::io`](http://doc.rust-lang.org/std/io/), `mod mem`
117+
provides implementations for
118+
[`BufReader`](http://doc.rust-lang.org/std/io/struct.BufReader.html)
119+
and
120+
[`BufWriter`](http://doc.rust-lang.org/std/io/struct.BufWriter.html),
121+
but these are re-exported in `io/mod.rs` at the top level of the module:
122+
123+
```rust
124+
// libstd/io/mod.rs
125+
126+
pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
127+
/* ... */
128+
mod mem;
129+
```
130+
131+
This hides the detail that there even exists a `mod mem` in `io`, and
132+
helps keep code organized while offering freedom to change the implementation.

0 commit comments

Comments
 (0)