Rust is fast, correct, safe and paired with an incredible developer experience. If you are starting a new project, you should absolutely use Rust rather than Java, Go, Python, or literally anything else. I fully stand by the claim that Rust is the best language we have created so far.
Let's use the rustup
toolchain manager to install rust, it's just like Node Version Manager and helps us keep track of our rust installations. Install it from Rustup to get started. This automagically installs Rust, Cargo, and the Rust Compiler (rustc).
In your editor, create a file called /app.rs
. This will be your first rust program π. We'll create your very first "Hello, World" program in it.
We then compile it just like C using rustc
. Make sure you are in the right folder and run:
This will create a file like app.exe
or a.out
in the same folder. Run that like
or
and it should print "Hello, World" to your terminal.
This is only the beginning π, we can do so much more with Rust by using Cargo. Firstly, install Rust Analyzer if you are using Visual Studio Code which will help us debug our programs and get syntax highlighting. Delete your previous executable files and code (it's mid and we don't want it anymore), then create a β¨Cargoβ¨ project:
This creates a binary project, we can also use --lib
to create a library which is just a package that can be used in other packages. Your binary file structure should look like this:
.
βββ src/
β βββ main.rs
βββ .gitignore
βββ Cargo.toml
The /src
folder is where our wonderful code will be located, the /src/main.rs
file is the entrypoint of our application and when we run our code, it will run this first. The .gitignore
is just a list of files to hide from society and Cargo.toml
is where we outline the information about our project, including its name, version, and importantly it's dependencies (or which libraries it's using)
Thankfully, the main.rs
file should already contain the Hello World program. Let's run it using Cargo with
This should build and compile our project and it's dependencies, save it in the /target
directory and then run it.
Amazing π
Let's create an app for ordering coffee online. Let's create the coffee class by going
We want to be able to let customers choose between Flat Whites, Espresso, and Frappe's. We can use an enum for this, which is just an object with predefined options.
Let's add some milk as well
Though, we may not always want milk in our coffee. In Rust, there is no null or undefined object, everything must be defined. To get around this, we can use the Option Enum. Options are just an enum with two variants, Some and None. It looks like this:
where T is a generic that can represent anything-- milk in our case. Options work so well in Rust because they pair well with matching statements. We can easily run a different function or behaviour based on which variant we are using, for example:
Great! We can finally create our coffee struct
Imagine though, we also had a Tea
struct. We want to be able to use one function to make both tea and coffee decaf for example. In Java, we may create a parent class called 'Drink', implement the decaf method, and then have Coffee and Tea inherit it. In Rust, we use traits. Let's create a trait called Decaffeinatable.
Let's implement our trait for our coffee
That was really easy, let's create an instance of Coffee with caffeine, and remove it afterwards
This is going to give us an error because by default everything in Rust is immutable which means you cannot change it by, for example, removing the caffeine. We have to declare the coffee as mutable and changable to begin with. This helps solve a lot of errors
Just like that we can remove the caffeine very easily and we have a standard way to remove the caffeine from any drink we may make.
Let's move on and create a web server so people can order online.
Run this command in your project directory to add all of the packages we need to our project.
Firstly, we need to make sure that our coffee is deserializable, which just means that we can accept it in our endpoints and in our servers from JSON. Let's use the serde
crate for that. It has a trait called Deserializable
. Instead of implementing that for our coffee struct ourself, we can 'derive' it, which means let serde automatically implement that trait for us (how convenient!).
Add
above our structs like this:
It needs to be above all of them for it to work. Let's create the basic layout for our app:
This is going to create an async web server that responds to requests on '0.0.0.0:3000/' with "Hello, World". Run it with cargo run
. Now let's create a way to store our orders in memory (we can easily expand and add a MongoDB or a SQL database in the future to save it).
Update the start of your app with this:
We are using an Arc to let us access the data between threads so our app runs very very fast, a Mutex to let us mutate and change that data even if it is being used between threads, and a Vector which is just a dynamically sizable array for storing our Coffee orders.
Let's create our order endpoint
Make sure you are importing everything you use at the top to make sure it works. Here, we create our order function which takes in two things. The current state which is a list of orders that have already been made, and a Json object of a coffee, that we add to our list of existing orders and then return a response with the status code created. Let's create one last endpoint to read all of our orders from.
You'll need to derive some more traits for our Coffee class. Add this to the top of all of your enums and structs for coffee
Then create the endpoint orders
This takes in our existing orders states and returns the Coffees as JSON. Add this to our router:
Then run your app with cargo run
and use Postman to test it
Try using a Milk or CoffeeType that isn't one of the options you defined or a negative number for sugar count. You didn't even need to write any code to check it, and the server comes with built-in error handling. You just created the fastest web server you've ever done, with built-in error handling. That's Rust.
If you would like to continue learning, I would highly recommend the Rust Book which is how I got started two years ago. I was sitting in my bedroom writing enums in Typescript and my next door neighbour walked in to invite me down to dinner and said "what are you doing!?! you should learn Rust".
See the full code on Github