Module Forms
This section describes what a module is and the two on-disk forms a module can take: a file module and a directory module.
A module is a Rue source file. The top-level items of the file — functions, structs, enums, and constants — are the members of the module.
A file module is a source file {name}.rue. An import of {name} that resolves to this file yields the module defined by it.
A directory module is a directory {name}/ that contains a facade file _{name}.rue directly inside it. The facade file is the directory module's root: an import of {name} that resolves to the directory module yields the module defined by the facade file. Other files inside the directory are not automatically part of the imported module; the facade reaches them via its own imports.
A file _{name}.rue is a facade only when its enclosing directory is named {name}. Anywhere else — in particular, as a sibling of a directory or a file named {name} — it is an ordinary source file with no special meaning, and it does not make {name} importable.
If both module forms exist for the same import path — a file module {path}.rue and a directory module {path}/_{basename}.rue — the import is ambiguous and rejected at compile time; neither form takes precedence. This is specified as rule 4.13:89 (error E0708).
A project mixing both forms:
main.rue # root file
math.rue # file module: @import("math")
utils/ # directory module: @import("utils")
├── _utils.rue # facade — the module root for "utils"
└── strings.rue # helper file, reached via the facade's imports