|
4 | 4 |
|
5 | 5 | > We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
|
6 | 6 | > 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