More about Cargo and Crates.io1
Note: There is no program included in this chapter, as it's notes only.
Cargo has two main profiles, dev
and release
dev
:cargo build
; good defaults for development.release
:cargo build --release
; good defaults for release builds.
However, it's possible to customize them:
# Cargo.toml
# These are the default values, as this is just an example.
[profile.dev]
# Compile faster, even if the code runs slower.
opt-level = 0
[profile.release]
# Compile slower, in order to make the code run faster.
opt-level = 3
See also: https://doc.rust-lang.org/cargo/reference/profiles.html.
The site crates.io is used to publish and pull (mostly) open source code.
Using ///
is a documentation comment, to generate HTML documentation:
/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
cargo doc --open
: will open the HTML for your current crates' documentation.
Other commonly used sections, other than # Examples
, are:
- Panics: Which scenarios the function documented could panic.
- Errors: If the function returns a
Result
, what kinds of errors might occur and what conditions might cause those errors to be returned. - Safety: If the function is
unsafe
, why the function is unsafe and covering hte invariants that the function expects callers to uphold.
One nice aspect is you can use cargo test
to run code examples as tests!
NOTE: That's why many code snippets have asserts in the examples.
To describe the crate, use //!
syntax:
//! # My Crate
//!
//! `my_crate` is a collection of utilities.
/// Adds one to the number given.
pub fn add_one(x: i32) -> i32 { /* ... */ }
In order to avoid having to add direct dependencies on other crates in order
to use a crate, pub use
will both use
(import) and re-export the paths:
//! # Art
//!
//! A library for modeling artistic concepts.
pub use self::kinds::PrimaryColor;
pub use self::kinds::SecondaryColor;
pub use self::utils::mix;
pub mod kinds {
// --snip--
}
pub mod utils {
// --snip--
}
You create an account at crates.io with a GitHub account, and then login:
# API key comes from https://crates.io/me/
# Will authenticate and store a SECRET token in in ~/.cargo/credentials
cargo login abcdefghijklmnopqrstuvwxyz012345
More metadata is required to publish a crate:
# Cargo.toml
[package]
name = "guessing_game"
version = "0.1.0"
edition = "2021"
description = "A fun game where you guess what number the computer has chosen."
license = "MIT OR Apache-2.0"
See also: https://doc.rust-lang.org/cargo/
tl;dr: cargo publish
.
tl;dr: cargo yank --vers 1.0.1
.
NOTE: This doesn't remove it, but will refuse being added to new projects.
Or, to undo: cargo yank --vers 1.0.1 --undo
.
A workspace is a set of packages that share the same Cargo.lock and outputs.
NOTE: This repository itself is a workspace containing all book chapters!
# /Cargo.toml
[workspace]
members = [
"adder",
"add_one",
]
├── Cargo.lock
├── Cargo.toml
├── add_one
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── adder
│ ├── Cargo.toml
│ └── src
│ └── main.rs
└── target
//! adder/src/main.rs
use add_one;
fn main() {
let num = 10;
println!("Hello, world! {num} plus one is {}!", add_one::add_one(num));
}
tl;dr: Use binary crates locally (i.e. install tools from crates.io).
$ cargo install ripgrep
Updating crates.io index
Downloaded ripgrep v11.0.2
Downloaded 1 crate (243.3 KB) in 0.88s
Installing ripgrep v11.0.2
--snip--
Compiling ripgrep v11.0.2
Finished release [optimized + debuginfo] target(s) in 3m 10s
Installing ~/.cargo/bin/rg
Installed package `ripgrep v11.0.2` (executable `rg`)
Cargo is designed so you can extend it without having to modify Cargo.
If a binary in your $PATH
is cargo-something
, run using cargo something
.
TIP: List custom commands by running
cargo --list
.You can even use
cargo install
to install extensions and run them like this!