- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
Guided: Data Structures in Rust
This lab is meant to serve as an exercise for fundamental Rust concepts such as Structs, Enums, and Pattern Matching. These data structures and their logic will be implemented through a series of guided steps. Once implemented, they will then be used to complete a fully functioning product management system.
Lab Info
Table of Contents
-
Challenge
Introduction
The goal of this lab is to complete the implementation for a product management application in Rust. Your tasks will involve the implementation and logic for two key data structures. The first will be a
Categoryenum that represents the type of the product such as a food, electronic, or furniture item. The second will be aProductstruct which represents the actual products in the inventory, including data such as their names, categories, prices, and quantities.You will also utilize the concept of pattern matching for the method implementations of these data structures to perform functions such as adding, removing, editing, and filtering for certain products in the inventory. Some other Rust features that you will be exposed to include the built-in
Optionenum and closures.At the end of the lab, you will be incorporating the implemented data structures into the main application logic to make the application fully functional. You can then run the application by clicking the Run button in the Terminal or inputting
cargo runinto the Terminal. Feel free to also checkout the solution directory if you get stuck. -
Challenge
Step 1: Category Enum
The first data structure you will implement is the
Categoryenum. Enums, short for enumerations, are custom data types that have a set of distinct values called variants. Each variant represents a state in which any variable of this enum type can be at any given time. For those who may be familiar with this concept in other languages such as C/C++ or Java, the concept is very much the same in Rust.The
Categoryenum is necessary here because it represents the types of products in the inventory, which can be eitherFood,Electronic, orFurniture. Enums in Rust can have methods implemented for them, as seen in theimpl Categoryblock. Currently, the only method isget_category()which you will need to implement. You will need to utilizematchstatements in this method, which is a pattern matching construct in Rust for executing code depending on a certain condition.matchstatements follow the following format:match variable { condition a => { execute code }, condition b => { execute code }, condition c => { execute code }, _ => { execute code } }This is very similar to switch statements from other languages, where if the
variablemeets a specific condition, only that block of code is executed. The final condition with the_functions like adefaultcase meant to be a catch-all for any conditions that are not specified or not important.The reason this is sometimes needed is because
matchstatements are exhaustive; in other words, EVERY single possible value for the variable must have a condition. When usingmatchwhere every possible value is addressed, this statement is not necessary. However, if you were tomatchto an integer value where you only want to do something if the value was 1, 2, 3, or 4, you would absolutely need this because the Rust compiler requires that ALL possible integer values be addressed.Another important detail is that the
_catch-all should always come last in amatchstatement because the order of amatchis always top-down. If it was first, none of the other conditions would evaluate because the_would always be matched first. -
Challenge
Step 2: Product Struct
Now you will need to implement the
Productstruct.Productis also a data structure likeCategory, but this time it's a struct instead of an enum. Structs in Rust function similarly to classes in other languages and are typically used for object-oriented programming.In
product.rs, you will find that theProductstruct has already been defined. Each field has been markedpubto allow it to be visible in other modules, and each field has also had its type specified. You will be responsible for completing each method within theimplblock. In the next two methods, you will be exposed to 3 more Rust features. The first is theOptionenum, which is a built-in Rust enum that has 2 variants. These variants areSome(), andNone. Since Rust does not have anullvalue, theOptionenum is typically used for any actions that may not return a value. If a value is returned, then theOptionis contains that value inSome(value). If not, then theOptionis of theNonevariant.Next is closures. Closures in Rust are just like anonymous/lambda functions in other languages. They are typically seen in the format
function_with_callback(|a| BODY). In this case, the closure is the entire expression within the parentheses. As an example, if you wanted to filter an array of numbers in Javascript to only include values greater than 5, you would do something along the lines ofarray.filter(x => x > 5). The Rust closure equivalent for thex => x > 5expression would be|x| x > 5.Lastly, another form of pattern matching you will be using here is an
if letas an alternative tomatch. For example:let example = function_that_returns_option(); match example { Some(i) => do_something(), //Since Option can only be Some or None, you could replace None with _ here None => {} // means do nothing }; //Only executes if example is Some(), doesn't do anything if it is None if let Some(i) = example { do something }In the event that you only care about a single specific condition,
if letallows you to be far more compact than having to write out a fullmatchstatement with actions for the conditions that you don't care about. -
Challenge
Step 3: Incorporating into main application
Now that you have defined and implemented both
CategoryandProduct, you will now need to utilize them in the application throughmain.rs. You will notice inmainthat there is anothermatchstatement that performs actions based on the user input and it will be your task to add the appropriate function calls fromCategoryandProductto the correct input cases. With all the tasks done, the application is now fully functional! Running the application will prompt you with options to either add, remove, or edit aProduct. The search function allows you to retrieve all products that contain the specified keyword, while the show all option will display all products currently in the inventory. -
Challenge
Epilogue
If you'd like to play around some more with the application after completing the lab, feel free to do so! For instance, adding more variants to
Category(remember to address them inget_category()) or some other methods to theCategoryimplementation. Perhaps you could also modifyedit_productto change its name or category as well!Although there won't be any tasks for you in whatever you'd like to do, you can always run
cargo check(to check that your code will compile) orcargo runto test any edits you make. The Rust compiler is very specific on what issues your code may have and you should definitely get used to reading its output when working on any Rust applications!
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.