Victor Kropp

Playing with Rust

Ferris 3D model by Ray March

Ferris 3D model by Ray March

I wanted to learn the Rust programming language for quite some time already. And last year I got a nice opportunity to do so.

JetBrains has announced RustRover—an IDE built specifically for Rust. And in the Toolbox App we had a task perfectly suited to be a first small program in the new language.

I started writing this blog post after completing the original task, but decided to test my skills on a few more occasions before publishing it.

So here are my notes as a Rust newbie.

Task 1. Helper tool

The task was to create a native messaging host application for the browser extension.

If you haven’t used the extension before, it helps you to quickly open any GitHub project right in your favorite IDE. But to know what your favorite IDE is and what else you have installed, it needs to communicate with the application. Here the helper app comes into play. Both extension and installed app register themselves, letting the browser know it can trust them.

In our case, the extension then gets the list of installed IDEs on the user’s computer. Before that, it needed to guess, and it didn’t work well in many cases.

At first, we tried implementing the helper in Kotlin Native and were not satisfied with the result. I then made an attempt to re-implement it in Rust.

Ecosystem

Rust ecosystem is huge. It seems that for every need there is already a crate (a redistributable package in the Rust world). And what’s even more impressive, all the crates I’ve seen so far are of great quality and are well-maintained.

For example, there is one implementing native messaging protocol. But since it is pretty straightforward, I decided to not use the existing solution and instead implement it myself.

Talking to a browser requires sending and receiving JSONs. And here Rust features a great serde crate, which implements serialization and deserialization for your structures in the compile time. Neat! I like the similar approach in kotlinx.serialization.

Borrow checker

It went surprisingly well, and even the borrow checker wasn’t able to spoil the party. In fact, in such a simple case, the most straightforward solution one implements is the best. It is readable, works fast and doesn’t require complicated mutability. Which means you don’t need to deal with the borrow checker.

Error handling

Error handling is also nicely integrated into the language. I prefer this explicitness over hidden exceptions in languages like Java and C++. On the other hand, it is much less ugly than in Go.

Performance

My program is fairly simple and works instantly, as expected. The compilation and build infrastructure is much easier to set up than we had to do with C++. And I hope that we’ll be able to replace all native pieces written in C++ we have right now with Rust.

Task 2. Advent of Code

After completing the extension helper, I worried that my Rust skills would become a bit rusty (pun intended). As the next challenge, I decided to solve Advent of Code in Rust this time. This worked (un)surprisingly well.

One doesn’t need blazing fast performance to solve Advent of Code tasks, but they are small and easy enough to try a new language.

Iterators

The only thing bothered me everytime, was the need to call .iter() and .collect() almost every time I wanted to process a collection. Iterators in Rust are complicated. I’m not used to it in Kotlin.

Task 3. Small webserver

My personal website, which you are reading now, is statically generated with Hugo (highly recommend it by the way). I’m satisfied with this approach, however, sometimes I want to add some interactivity to some pages.

For example, I recently added a ’now playing’ tile to my now page, which shows the current music I’m listening to on Spotify. And again, to hone my Rust skills, I’ve implemented the API endpoint for this in Rust.

There are already established libraries for this task: tokio for asynchronous tasks, axum as the Web framework, and reqwest for HTTP requests. I may have used Spotify API wrappers or existing OAuth2 clients, but decided to just issue few raw requests to refresh token and checking the player state.

I cache the current music in memory for a few minutes to throttle Spotify API requests. If there is a valid response, it is served instantly from the memory.

It took me just a few hours to build the whole thing, so I’m pretty happy with it.

I’ve enjoyed my first Rust experience and hope I’ll get a chance to apply it in other real-world projects.

programmingrust

Subscribe to all blog posts via RSS