Rust low-level bindings to libzmq

ZeroMQ is a lightweight messaging
library which makes it fairly easy for developers to design and
implement distributed systems.

ZeroMQ comes with a pretty nice API, so getting started with it is
quite easy. Lots of languages also provide bindings to the libzmq
library, so you could already get started with ZeroMQ using your
favourite language of choice.

Perhaps the best place to get started with ZeroMQ is to head over
to the ZeroMQ Guide which
will teach you about ZeroMQ by going through various
examples and problems and show you how to solve them using the
library.

I’ve been using ZeroMQ for quite some time already and implemented a
few distributed systems with it, mostly written in Python and C.

These days I’m trying to learn myself a bit of
Rust, which is a systems programming
language with focus on safety, speed and concurrency.

Being a new language, Rust comes with some new concepts not found in
other languages. One of them is the
Rust Ownership System,
which takes a bit of time getting used to it.

So far I really enjoy programming in Rust, and I really like how
nice and easy the language can bind into existing C libraries
using the
Rust FFI interface,
so as one of the first Rust projects I’ve decided to work on is
low-level bindings to the ZeroMQ messaging library.

Of course it would be much easier to get the existing Rust ZeroMQ
bindings up to speed with the latest libzmq version, but
these bindings have been generated by
rust-bindgen, which is a
binding generator and a really cool project, but the thing is that
rust-bindgen generates a slightly different Rust code on my system
than the one I can already find in the existing repository.

I bet that others would also get different Rust code if they ran
rust-bindgen on their systems as well, depending on what Rust
version they have, OS and probably some other factors. And also
the resulting Rust code as generated by rust-bindgen does not
always look as pretty as it would if it was written by a human.

I’m not saying that rust-bindgen is bad, it’s just that I think
for a library such as the
ZeroMQ C API,
which comes with a really nice and small factor API it’s simply not
worth creating the bindings via an automatic generator, when we can
always easily translate them into Rust.

The code below is what represents our src/main.rs file from our
Rust project. When you build and run it, it will print the version
of your libzmq library.

externcratelibc;externcratelibzmq;unsafefnprint_version(){letmutmajor=0;letmutminor=0;letmutpatch=0;libzmq::zmq_version(&mutmajor,&mutminor,&mutpatch);println!("Installed ZeroMQ version is {}.{}.{}",major,minor,patch);}fnmain(){unsafe{print_version();}}

And here is the client part of our project, which will connect to our
server by using a ZeroMQ ZMQ_REQ socket and connect it to the
tcp://127.0.0.1:5555 endpoint. It will then send ten messages to
the server and exit.

Once ready, simply build the projects and run them. You should now
see ZeroMQ messages passing back and forth between our client and
server.

You should also note that our functions are actually marked as
unsafe, which is
required since we are calling foreign code via the
Rust FFI interface.

Further improvement on this code would be to actually write a nice
high-level wrapper around these low-level bindings that would make
use of Rust’s main features on safety, but I’ll leave that for
some other day.