Skip to main content

Rust all-in

A language empowering everyone to build reliable and efficient software.

The most important links when working with Rust (alphabetically):

Other awesome links (alphabetically):

Interesting Stack Overflow questions

Difference between iter, iter_mut, and into_iter

  • the iterator returned by into_iter may yield any of T, &T or &mut T, depending on the context
  • the iterator returned by iter will yield &T, by convention
  • the iterator returned by iter_mut will yield &mut T, by convention

If you just need to "look at" the data, use iter, if you need to edit/mutate it, use iter_mut, and if you need to give it a new owner, use into_iter.


Difference between Copy and Clone

Copies happen implicitly, for example as part of an assignment y = x. The behavior of Copy is not overloadable; it is always a simple bit-wise copy.

Cloning is an explicit action, x.clone(). The implementation of Clone can provide any type-specific behavior necessary to duplicate values safely. For example, the implementation of Clone for String needs to copy the pointed-to string buffer in the heap. A simple bitwise copy of String values would merely copy the pointer, leading to a double free down the line. For this reason, String is Clone but not Copy.

Clone is a supertrait of Copy, so everything which is Copy must also implement Clone. If a type is Copy then its Clone implementation only needs to return *self:

struct MyStruct;

impl Copy for MyStruct { }

impl Clone for MyStruct {
fn clone(&self) -> MyStruct {


Different wording:

  • Copy is implicit, inexpensive, and cannot be re-implemented (memcpy)
  • Clone is explicit, may be expensive, and may be re-implement arbitrarily

Read this interesting question:

Visibility and privacy in Rust

Visibility and privacy o modules in Rust is well explained here:

In short: (almost) everything is private by default and you can make it public via pub keyword. There are several additional restrictions of the pub keyword:

  • pub(in path) makes an item visible within the provided path. path must be an ancestor module of the item whose visibility is being declared.
  • pub(crate) makes an item visible within the current crate.
  • pub(super) makes an item visible to the parent module. This is equivalent to pub(in super).
  • pub(self) makes an item visible to the current module. This is equivalent to pub(in self) or not using pub at all.


pub mod outer_mod {
pub mod inner_mod {
// This function is visible within `outer_mod`
pub(in crate::outer_mod) fn outer_mod_visible_fn() {}

// This function is visible to the entire crate
pub(crate) fn crate_visible_fn() {}

// This function is visible within `outer_mod`
pub(super) fn super_mod_visible_fn() {
// This function is visible since we're in the same `mod`

// This function is visible only within `inner_mod`,
// which is the same as leaving it private.
pub(self) fn inner_mod_visible_fn() {}
pub fn foo() {

// This function is no longer visible since we're outside of `inner_mod`
// Error! `inner_mod_visible_fn` is private

fn bar() {
// This function is still visible since we're in the same crate

// This function is no longer visible since we're outside of `outer_mod`
// Error! `super_mod_visible_fn` is private

// This function is no longer visible since we're outside of `outer_mod`
// Error! `outer_mod_visible_fn` is private


fn main() { bar() }

How to create parameterized tests in Rust?

macro_rules! fib_tests {
($($name:ident: $value:expr,)*) => {
fn $name() {
let (input, expected) = $value;
assert_eq!(expected, fib(input));

fib_tests! {
fib_0: (0, 0),
fib_1: (1, 1),
fib_2: (2, 1),
fib_3: (3, 2),
fib_4: (4, 3),
fib_5: (5, 5),
fib_6: (6, 8),

An interesting alternative approach is to use proptest:

proptest! {
fn parses_all_valid_dates(s in "[0-9]{4}-[0-9]{2}-[0-9]{2}") {

Or with extra config:

proptest! {
#![proptest_config(ProptestConfig {
cases: 1000, .. ProptestConfig::default()
fn parse_authorization_header_proptest(token in "[a-zA-Z0-9-._~+/]+") {
println!("Bearer {}", token); // visible only with `cargo test -- --nocapture`
let result = parse_authorization_header(format!("Bearer {}", token).as_str()).unwrap();
prop_assert_eq!(result, token)

Reading and writing files

Read a file to a String:

use std::fs;

fn main() {
let data = fs::read_to_string("/etc/hosts").expect("Unable to read file");
println!("{}", data);

Read a file as a Vec<u8>:

use std::fs;

fn main() {
let data = fs::read("/etc/hosts").expect("Unable to read file");
println!("{}", data.len());

Write a file:

use std::fs;

fn main() {
let data = "Some data!";
fs::write("/tmp/foo", data).expect("Unable to write file");

Macro repetitions

Below is a macro which formats each element as a string. It matches zero or more comma-separated expressions and expands to an expression that constructs a vector.

macro_rules! vec_strs {
// Start a repetition:
// Each repeat must contain an expression...
// ...separated by commas...
// or more times.
) => {
// Enclose the expansion in a block so that we can use
// multiple statements.
let mut v = Vec::new();

// Start a repetition:
// Each repeat will contain the following statement, with
// $element replaced with the corresponding expression.
v.push(format!("{}", $element));


fn main() {
let s = vec_strs![1, "a", true, 3.14159f32];
assert_eq!(s, &["1", "a", "true", "3.14159"]);


Ultimate Clippy pedantic check

cargo clippy -- -W clippy::pedantic