]> git.lizzy.rs Git - rust.git/blob - src/doc/style/features/modules.md
Changed issue number to 36105
[rust.git] / src / doc / style / features / modules.md
1 % Modules
2
3 > **[FIXME]** What general guidelines should we provide for module design?
4
5 > We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
6 > around modules.
7
8 ### Headers [FIXME: needs RFC]
9
10 Organize module headers as follows:
11   1. [Imports](../style/imports.md).
12   1. `mod` declarations.
13   1. `pub mod` declarations.
14
15 ### Avoid `path` directives. [FIXME: needs RFC]
16
17 Avoid using `#[path="..."]` directives; make the file system and
18 module hierarchy match, instead.
19
20 ### Use the module hierarchy to organize APIs into coherent sections. [FIXME]
21
22 > **[FIXME]** Flesh this out with examples; explain what a "coherent
23 > section" is with examples.
24 >
25 > The module hierarchy defines both the public and internal API of your module.
26 > Breaking related functionality into submodules makes it understandable to both
27 > users and contributors to the module.
28
29 ### Place modules in their own file. [FIXME: needs RFC]
30
31 > **[FIXME]**
32 > - "<100 lines" is arbitrary, but it's a clearer recommendation
33 >   than "~1 page" or similar suggestions that vary by screen size, etc.
34
35 For all except very short modules (<100 lines) and [tests](../testing/README.md),
36 place the module `foo` in a separate file, as in:
37
38 ```rust,ignore
39 pub mod foo;
40
41 // in foo.rs or foo/mod.rs
42 pub fn bar() { println!("..."); }
43 /* ... */
44 ```
45
46 rather than declaring it inline:
47
48 ```rust,ignore
49 pub mod foo {
50     pub fn bar() { println!("..."); }
51     /* ... */
52 }
53 ```
54
55 #### Use subdirectories for modules with children. [FIXME: needs RFC]
56
57 For modules that themselves have submodules, place the module in a separate
58 directory (e.g., `bar/mod.rs` for a module `bar`) rather than the same directory.
59
60 Note the structure of
61 [`std::io`](https://doc.rust-lang.org/std/io/). Many of the submodules lack
62 children, like
63 [`io::fs`](https://doc.rust-lang.org/std/io/fs/)
64 and
65 [`io::stdio`](https://doc.rust-lang.org/std/io/stdio/).
66 On the other hand,
67 [`io::net`](https://doc.rust-lang.org/std/io/net/)
68 contains submodules, so it lives in a separate directory:
69
70 ```text
71 io/mod.rs
72    io/extensions.rs
73    io/fs.rs
74    io/net/mod.rs
75           io/net/addrinfo.rs
76           io/net/ip.rs
77           io/net/tcp.rs
78           io/net/udp.rs
79           io/net/unix.rs
80    io/pipe.rs
81    ...
82 ```
83
84 While it is possible to define all of `io` within a single directory,
85 mirroring the module hierarchy in the directory structure makes
86 submodules of `io::net` easier to find.
87
88 ### Consider top-level definitions or reexports. [FIXME: needs RFC]
89
90 For modules with submodules,
91 define or [reexport](https://doc.rust-lang.org/std/io/#reexports) commonly used
92 definitions at the top level:
93
94 * Functionality relevant to the module itself or to many of its
95   children should be defined in `mod.rs`.
96 * Functionality specific to a submodule should live in that
97   submodule. Reexport at the top level for the most important or
98   common definitions.
99
100 For example,
101 [`IoError`](https://doc.rust-lang.org/std/io/struct.IoError.html)
102 is defined in `io/mod.rs`, since it pertains to the entirety of `io`,
103 while
104 [`TcpStream`](https://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
105 is defined in `io/net/tcp.rs` and reexported in the `io` module.
106
107 ### Use internal module hierarchies for organization. [FIXME: needs RFC]
108
109 > **[FIXME]**
110 > - Referencing internal modules from the standard library is subject to
111 >   becoming outdated.
112
113 Internal module hierarchies (i.e., 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`](https://doc.rust-lang.org/std/io/), `mod mem`
117 provides implementations for
118 [`BufReader`](https://doc.rust-lang.org/std/io/struct.BufReader.html)
119 and
120 [`BufWriter`](https://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,ignore
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
133 implementation.