Optional dependencies in Rust

Yes, I’m learning a new language. A typed one =D I love C++. Some of my best code and all my research was done in C++. But I hate its dependency system. I don’t want to deal with them anymore. So here it is Rust, that feels as an appointed heir.

I don’t want to extend this post more than necessary, so I will get to the point. Rust can defined dependencies. Dependencies can be optional. Besides, we can optionally include dependencies or blocks of code using features.

To define a feature, you define it in your Cargo.toml

rand = "^0.7.3"
ndarray = "^0.13.1"
log = "^0.4.11"
image = "^0.23.11"
imageproc = "^0.21.0"
sdl2 = {version = "^0.34.3", optional = true}

default = ["display-window"]
display-window = ["sdl2", "imageproc/display-window"]

We are here declaring a feature called display-window that includes the dependency sdl and the crate imageproc/display-window.

To activate that feature, you have to add a cfg macro in your .rs source.

#[cfg(feature = "display-window")]
use imageproc::window::display_image;

fn display_image() {
    let canvas = ...;
    let width = 2048;
    let height = 2048;
    imageproc::window::display_image("Title", canvas, width, height);

That code makes the feature display-window active, which enables us to use the imageproc::window space. We don’t see that in this code but imageproc::window requires sdl2 to work, and that’s the reason because we included the sdl2 crate in Cargo.toml.