« Back to Index

Rust: Packages, Crates, Modules

View original Gist on GitHub

Tags: #rust #rustlang #learn

Rust Learning Packages Crates Modules.md

Summary

Ref

Package

A package contains a Cargo.toml file that describes how to build the crates defined within the package.

A package must contain at least one crate, it can be either a ‘library’ crate or a ‘binary’ crate.

A package can contain multiple binary crates, but can only one library crate.

A package can have multiple binary crates by placing files in the src/bin directory: each file will be a separate binary crate.

Crate

To show Rust where to find an item in a module tree, we use a path in the same way we use a path when navigating a filesystem. If we want to call a function, we need to know its path.

This can be achieved using either an ‘absolute’ path or a ‘relative’ path.

Filename: src/lib.rs

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

Module

You can define a module within the root library or binary crate or you can define them in separate files within the src directory.

Filename: src/foo.rs

// foo module

pub mod bar {
    pub trait Thing {
        fn do_thing(&self);
    }

    pub fn baz() {
        println!("baz called!")
    }

    #[derive(Debug)]
    pub struct SomeStruct {
        pub some_field: u8,
    }

    impl SomeStruct {
        pub fn new(some_field: u8) -> SomeStruct {
            SomeStruct { some_field }
        }
    }

    impl Thing for SomeStruct {
        fn do_thing(&self) {
            println!("do a thing");
        }
    }
}

Filename: src/main.rs

mod foo;

use crate::foo::bar;
use crate::foo::bar::Thing; // you must import the trait implemented for SomeStruct

fn main() {
    bar::baz();

    let ss = bar::SomeStruct::new(123);
    println!("{:?}", ss);
    println!("{}", ss.some_field);
    ss.do_thing();
}

NOTE: Using a semicolon after mod foo rather than using a block {...} tells Rust to load the contents of the module from another file with the same name as the module.