## Rust Has A Module System

• Better than most, not as good as SML

• Name-based, but with inter-module typechecking

• Two kinds of thing

• "Crates": self-contained packages
• "Modules": namespaces within a package
• http://crates.io is the big repository of published crates

## Library and Binary Crates

• A crate can correspond to a program that can be installed

• A crate can correspond to a library that can be published

• By default, directory structure gives Cargo what it needs

• src/main.rs is a "binary"
• src/lib.rs is a library
• src/mod.rs is a module top-level for a library
• You can override all of this in Cargo.toml

## Cargo Fetches Crates

• The [dependencies] section of Cargo.toml allows specifying other crates used by this crate

• This is by far the sanest way to do separate compilation

• Can specify

• crates.io crate: foo = "0.4"
• Github crate: foo = { git = "http://github.com/something/foo.git" }
• Local crate: foo = { path = "/local/src/foo" }
• Then you can use foo:: in your program, or use a use decl

## Namespaces

• Namespaces are :: separated as in some other languages

• std::io::stdin()
• use std::io::stdin; stdin(); io::stdin()
• The mod directive at the start of a block introduces a new namespace in the current spot

• Most of this machinery is available in any scope

## Modules In Separate Files

• In addition to explicit mod { ... } declarations, can make a file foo.rs a module by saying mod foo; at the top of its parent module.

• The filename is inferred from the module name, so be careful.

• You can also make a directory contain a module and its submodules by putting a mod.rs at the root of the directory.

## Making Things pub

• By default, nothing in a module is visible outside the module/crate in which it is declared

• You can put pub in front of an item to make it externally visible

• For things like structs and enums, the visibility of the thing and its fields is controlled separately

• The compiler will whine at you about an unused thing unless it is pub, in which case it assumes you just know it will be used somewhere

## Semantic Versioning

• Three-part version numbers: breaking.major.minor

• Supposedly improves stability

• Cargo.lock preserves Cargo's versioning choices

## Docs

• Doc comments have an extra slash ///. You can also have C-style doc comments //*

• Use cargo doc --document-private-items to get docs for stuff not visible outside the crate — useful for binaries

• Docs are formatted as Markdown

## Tests

• Tests and the #[test] and #[cfg(test)] and stuff