Book Image

Rust Standard Library Cookbook

By : Jan Hohenheim, Daniel Durante
Book Image

Rust Standard Library Cookbook

By: Jan Hohenheim, Daniel Durante

Overview of this book

Mozilla’s Rust is gaining much attention with amazing features and a powerful library. This book will take you through varied recipes to teach you how to leverage the Standard library to implement efficient solutions. The book begins with a brief look at the basic modules of the Standard library and collections. From here, the recipes will cover packages that support file/directory handling and interaction through parsing. You will learn about packages related to advanced data structures, error handling, and networking. You will also learn to work with futures and experimental nightly features. The book also covers the most relevant external crates in Rust. By the end of the book, you will be proficient at using the Rust Standard library.
Table of Contents (12 chapters)

How it works...

Whew, that's a lot of code! Let's start by breaking it up.

In the first part, we illustrate how to use this pattern to effortlessly configure a complex object. We do this by relying on sensible standard values and only specifying what we really care about:

let normal_burger = BurgerBuilder::new().build();
let cheese_burger = BurgerBuilder::new()
.cheese(true)
.salad(false)
.build();
let veggie_bigmac = BurgerBuilder::new()
.vegetarian(true)
.patty_count(2)
.build();

The code reads pretty nicely, doesn't it?

In our version of the builder pattern, we return the object wrapped in a Result in order to tell the world that there are certain invalid configurations and that our builder might not always be able to produce a valid product. Because of this, we have to check the validity of our burger before accessing it[7, 10 and 13].

Our invalid configuration is vegetarian(true) and bacon(true). Unfortunately, our restaurant doesn't serve vegetarian bacon yet! When you start the program, you will see that the following line will print an error:

if let Err(error) = invalid_burger {
println!("Failed to print burger: {}", error);
}

If we omit the final build step, we can reuse the builder in order to build as many objects as we want. [25 to 32]

Let's see how we implemented all of this. The first thing after the main function is the definition of our Burger struct. No surprises here, it's just plain old data. The print method is just here to provide us with some nice output during runtime. You can ignore it if you want.

The real logic is in the BurgerBuilder[64]. It should have one member for every value you want to configure. As we want to configure every aspect of our burger, we will have the exact same members as Burger. In the constructor [74], we can specify some default values. We then create one method for every configuration. In the end, in build() [109], we first perform some error checking. If the configuration is OK, we return a Burger made out of all of our members [121]. Otherwise, we return an error [119].