rust-101

Reading Time: 3 minutes

Rust is nice to learn, although the learning curve is quite a steep. Let’s start here with some basics on cargo and rust . You can download rust from Rust-Lang.org so we would just dive straight into working with rust

Cargo

cargo is the tool we’ll use to create, manage and compile projects. It’s sort of like Makefile or CMakeLists.txt but just a lot more nicer and easier to understand. The first command we’ll use is the new command which creates a new project for us including the manifest file called Cargo.toml

$ cargo new hello-world 

So this creates a new directory having the sources in the src directory. Also if you see the name of the project is hello-world in the generated Cargo.toml

We can change the name of the project and in this case it’ll be the name of the binary which is generated, so let’s take a look at Cargo.toml.

[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
 

We can change the name of the package here and that’ll be the name of the binary which is generated when we build this project. The project is called as crate in the rust world. This particular hello-world crate is a binary project, i.e. one that doesn’t create libraries but only a binary.  To create a library as well as a binary for the same project you need create a project using the --lib OR add a lib.rs in the src directory.

$ cargo new --lib hello-world  

Directory Structure

Cargo creates a directory structure that it understands and applies some hueristics on it. For example, adding the --lib flag to cargo doesn’t change anything in the Cargo.toml however it adds a lib.rs file in the src directory. Cargo understands this and builds a library as well as a binary with the name as specified in the Cargo.toml

.
├── Cargo.lock
├── Cargo.toml
└── src
    ├── lib.rs
    └── main.rs

1 directory, 4 files
 

The above is a listing of the current directory of the hello-world project. But when you build using cargo buildthen this creates a bunch of other files, quite a lot actually. The final output is present in the debug directory and if you use the --release flag then output would be in the release directory as shown below

├── Cargo.lock
├── Cargo.toml
├── src
│   ├── lib.rs
│   └── main.rs
└── target
    ├── CACHEDIR.TAG
    └── release

3 directories, 5 files
 

When you’ve a lib.rs as well as main.rs then both the binary and the library file would be created in the target directory. The library created is a static library by default, however if required we can also generate a shared library by changing the type of crate in Cargo.toml as shown below

[lib]
crate-type= ["lib", "dylib"] 

tests

This is a special directory recognized by cargoand it assumes that all tests are housed in this directory. So when we call cargo tests we tell cargo to run the tests in this directory. However the tests still required to be marked as tests. An example is shown here just for completion, 

.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── tests
    └── unit.rs
 

About modules and crates

cargo only knows that it needs to compile main.rs and lib.rs if present. Obviously not all of our code is going to be within a single file, so other files ending in .rs are separate modules. cargo has no clue about them thus we need to use them in either main or lib so that cargo can find these modules. There are two ways to do this,

  • using the use statement
  • using the mod statement.

The difference between them is, mod is used for code which you’ve access to, for example when writing your own projects

use is used when you want to have access to code that’s coming externally and you’re just using it NOT pulling it in your code verbatim.

crateis the toplevel module for each project, so it can contain modules and sub-modules. We’ll see more on this in some later blogs.

Until then have fun!

Leave a Reply