Bringing Rust to C#: Oxide and Oxide.Http
Rust is a language I’ve admired for a long time now, from a slight distance. I’ve read about the borrow checker, perused the standard crates, and read up on Cargo and the way that Rust applications and libraries are built, tested, and shipped. I appreciate its striving to be a systems-level language that also cares about safety and developer productivity.
I haven’t written as much Rust as I’d like to (though I did start a few small
projects here and there), but that didn’t stop me from thinking that maybe some
of its standard library features have a place in the C# world. I found myself
particularly fond of the Option and Result types, and
their ability to better the flow of my code. Option’s API is Nullable<T> on
steroids, and Result provides an elegant way to express an error that doesn’t
require using out parameters or custom exceptions, while at the same time
providing a delightful API that lets you build processing pipelines that
preserve errors and lazily evaluate steps.
The adventure started when one afternoon about a month ago, when I decided I
wanted to see if I could implement Option in C#. I knew I wanted to preserve
as much of the Rust API as made sense, including the simple construction of
Some and None as function calls: Some(5), None<int>(), etc. I opened
up Workbooks (use what you know, right?) and started hacking away.
After a little while, I had my first pass at the Option API surface—I
stuffed it in a Gist, Within a few hours, I decided to make it into a
library called Oxide—after all, what else is Rust?
My initial commit brought in the API almost exactly as it was in the
Gist. Over the rest of the day, I refined the API slightly, added a ton of tests
(inspired by the Rust documentation’s example assertions), and wrapped up. A
week later, I decided to add Result, which I implemented largely the same way
(a base class, with derived Ok<T, E> and Err<T, E> classes).
Since then I’ve refined the API for both, added a priority queue implementation, added a small library of HTTP helper methods (Oxide.Http), received my first external contribution from Jérémie Laval who contributed a very nice set of convenience methods to enable async/await with Option, and finally published a NuGet (when I was forced to by wanting to use Oxide in another project but wanted to avoid submodules).
I hope to keep working on Oxide—there will probably be more APIs that I would like to borrow from Rust, or more functional/Rust-inspired API that would be useful for C# developers. Contributions of all kinds are welcome: bug reports, feature requests, documentation, etc. You can find Oxide on GitHub—please use the issue tracker there for everything. :)
Leave a comment