Modules and crates

Crates and modules are used to organize code into separate namespaces, allowing for easier management of code and better code reusability.

A module is a named container for items such as structs, enums, functions, constants, and traits.

A crate is a single compilation unit. It has a root directory, and a root module defined at the file lib.cairo under this directory.

1. Defining a module

A module can be defined in two ways: inlined in the current file or in a separate file. When a module is defined in a separate file, the file is located according to the module hierarchy. For example, the module crate_name::a::b::c is defined in the file <crate_root_dir>/a/b/c.cairo.

a.cairo:

// This is a module defined in the current file.
mod foo {
    // ... items ...
}

// This is a module defined in `a/bar.cairo`.
mod bar;

2. Module hierarchy

The module hierarchy is defined by the module definitions in the source code. When a module is defined inside another module, it is called a submodule, and it can be referred to using its name. The module containing the current module is called the parent module, and can be referred to using the super keyword. The root module of a crate has no parent.

3. Module scope

Items defined inside a module are directly available within the module. In particular, items defined at outer modules are not directly available in inner modules, even when inlined. To refer to an item defined in another module, the item must be either fully qualified or imported with the use keyword. For more information, see Paths.

struct A {}
struct B {}

mod foo {
    use super::B;    // Import the struct `B` from the parent module.
    fn bar() {
        A {};        // This is not allowed, because `A` is not in scope.
        super::A {}; // This is allowed, because `super` refers to the parent module.
        B {};        // This is allowed, because `B` is imported.
    }
}