Rust Nibbles – Gazebo: Prelude

This article was written in collaboration with Neil Mitchell, a software engineer in the Developer Infrastructure organization at Facebook.

The Rust Gazebo Library contains a collection of proven Rust utilities. These aren’t deep or complex ideas, just small things that we believe can make a Rust programmer’s experience a little easier. This post is the first in a series that will explore some things in Gazebo. Let’s start with Prelude.

The Gazebo Prelude includes 5 extension features that add additional methods to Vec, Slice, Option, Str, and Iterators. These are intended as little helpers that make common patterns more concise or less prone to errors. We hope that some of these methods could be useful enough to get into the standard library one day. For example, it’s not uncommon to see the following pattern in Rust code:

let ys = xs.iter (). map (| x | x.abs ()). collect ::<_>> ();

We have a vector of integers and we want to create a vector of integers by mapping over each element. To do that, we first convert it to an iterator, then we map it, and finally we collect it back. Unfortunately, Rust can’t figure out the type of the result, so we need a type annotation for the collect call. Rust iterators are powerful, efficient, and composable, so it’s great to be able to do such a transformation so easily.

While this code isn’t terrible, this pattern shows up a lot, so it’s worth simplifying a little:

Use pavilion :: prelude :: *; let ys = (| x | x.abs ());

Now the code expresses our intention much more directly. The map function works on both Vec and Slices, with a corresponding into_map taking ownership of the elements, but only works on Vec. Under the hood, it does the exact same thing using iterators.

Other extension methods in Prelude apply to str and provide more flexible ways of splitting strings. For example:

Use pavilion :: prelude :: *; assert_eq! (“test” .split1 (‘e’), (“t”, “st”)); assert_eq! (“test” .split1_opt (‘e’), Some ((“t”, “st”))); assert_eq! (“test” .trim_start_match (“tes”), “t”); assert_eq! (“test” .trim_start_match_opt (“tes”), Some (“t”));

We’ve found that these methods provide some help when trying to parse a string “lightly” – simpler and less powerful than a regex or a full parser-combiner library like nom, but still useful. Unfortunately, these string methods are only available with Rust nightly, as building on the flexible string pattern matching requires the unstable pattern function.

Earlier versions of the Gazebo library contained the functions that appeared in the standard Rust library as strip_prefix and strip_suffix, so they are no longer available in Gazebo.

While there are other methods in the Prelude, we’ve found these to be the most common in our code. To see the others, visit the documentation.

We hope this blog helps you understand the Prelude module, how to use it, and gives you a good look at its features. Look out for our next blog in this series where we discuss the Dupe module that encodes the cheap clone pattern.

About the Rust Nibbles series

At Facebook, we believe that Rust is a stellar language that shines on critical issues like storage security, performance, and reliability. We have joined the Rust Foundation to contribute to the growth, advancement, and adoption of Rust, and the sustainable development of open source technologies and developer communities around the world.

This blog is part of our Rust Nibbles series where we’ll go over the various Rust libraries we’ve made open source to learn more about what motivates their creation and how to use them. We hope this series helps you create amazing projects using these libraries and encourages you to try them out.

To learn more about Facebook Open Source, visit our open source site, subscribe to our YouTube channel, or follow us on Twitter and Facebook.

Comments are closed.