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

Commit bdbf206

Browse files
features/modules: Expand modules section
1 parent 8df09d4 commit bdbf206

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

features/modules.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,84 @@
44
55
> We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
66
> around modules.
7+
8+
## Basic design
9+
10+
> **[OPEN]** This documents the simple, common pattern of module
11+
> design - but others exist and improvements are appreciated.
12+
13+
The file `mod.rs` in a module defines the base-level imports of the
14+
module. For all except trivial modules (and
15+
[test cases](../testing/README.md)), it is better to keep this in a
16+
separate file.
17+
18+
A big use of `mod.rs` is to define a common interface for your module. The
19+
internal structure can be whatever form that you might like, but then
20+
this code will all get re-exported in `mod.rs` to the rest of the world.
21+
22+
This also serves a convenience purpose: users of your module only have
23+
to remember the module name, and you can keep whatever internal
24+
structure is required.
25+
26+
For example, say we had the following folder structure:
27+
28+
```
29+
myio/mod.rs
30+
/mem.rs
31+
/terminal/mod.rs
32+
```
33+
34+
where we wish to keep `mem.rs` hidden from the outside world, and make
35+
usage of `terminal` an explicit submodule. In `myio/mod.rs` we would
36+
write:
37+
38+
```rust
39+
// myio/mod.rs
40+
41+
pub use self::mem::MemReader;
42+
43+
mod mem;
44+
pub mod terminal;
45+
```
46+
47+
### Export common traits, structs, and enums at the module level
48+
49+
> **[OPEN]**
50+
51+
In the above example, we re-export `MemReader`, but we might have others
52+
that are common to the whole module, and not just `mem.rs`:
53+
54+
```rust
55+
// myio/mod.rs
56+
57+
pub enum FileMode { /* ... */ }
58+
pub trait Seek { /* ... */ }
59+
pub struct File { /* ... */ }
60+
```
61+
62+
Then, to use these common traits in submodules:
63+
64+
```rust
65+
// myio/mem.rs
66+
67+
use super::Seek;
68+
69+
pub struct MemReader { /* ... */ }
70+
impl MemReader { /* ... */ }
71+
impl Seek for MemReader { /* ... */ }
72+
```
73+
74+
Notice how both `Seek` and `MemReader` are both visible from
75+
`myio::Seek` and `myio::MemReader`.
76+
77+
### Use private modules to hide information
78+
79+
> **[OPEN]**
80+
81+
This structure lets you achieve the goals of information hiding (the
82+
implementation of `mem` is separate from the `MemReader` in our API) and
83+
making all useful types available for the internal modules.
84+
85+
It is good practice to keep code that is likely to change hidden in this
86+
manner, and only make public the parts that constitute the module's
87+
interface.

0 commit comments

Comments
 (0)