My first programming IDE back in the 90s was Borland Turbo Pascal. Since
the PC that I used at that time was running MS-DOS, it meant no graphical
interface. I was so surprised when I ran turbo.exe for the first time
and saw complex menus, dialog windows and an editor with code highlighting.
But the world of TUI (text-based user interfaces) doesn't mean only IDEs.
Midnight Commander is a very popular
and feature-rich file browser. There are even text-based web browsers,
such as Lynx or
TUI applications tend to use ncurses
as the abstraction layer over different terminals.
While there are Rust bindings to ncurses, there's another cool library built
on top of them. Cursive provides
high-level building blocks such as views, menus and layers. It also works
on Windows, when built with features = ["pancurses"].
The zip crate is the most commonly used
Rust library for manipulating ZIP archives. It supports reading and writing
.zip files with different compression methods (store, deflate, bzip2).
There are at least three crates for LZMA (de)compression on crates.io.
lzma is pure Rust, but currently allows
only reading from archives.
rust-lzma supports both reading
and writing compressed data, but it's a wrapper for liblzma. Similarly
the xz2 crate is a binding for liblzma.
clap is a fantastic Rust library
for Command Line Argument Parsing. It's both
easy to use and powerful - in the spirit of Rust philosophy - you get what
you pay for. Simple CLI options are simple to define, while complex schemes
(think git level of complex) are absolutely doable.
clap is also one of the best examples of what I would call
developer marketing in the Rust community. It has a
beautiful and informative homepage, an extensive
README (including changelog - see note
below), a bunch of
good examples, even
Hats off to Kevin and all clap contributors, you're doing a great job!
Note: Rust crate authors, please, please add changelogs/release notes to
your libraries. Coming from Python where it's customary, it struck me that
a lot of libraries do not document their changes aside from the commit log.
(Oops, I'm guilty of this myself...)
We learned the basic concepts of nomyesterday
when we wrote a parser for HTTP headers. HTTP is by its nature a text protocol.
nom however always works on bytes (byte array slices, denoted in Rust with
&[u8]). This makes it perfectly suitable for parsing binary data as well.
There's already a selection of parsers using nom for binary formats such as
Redis dump files,
or tar archives. Today we are going
to build a simplified WebSocket frame parser.
It's entirely possible that you're walking a happy road of a programmer
who never had to write a parser by hand. That's not my case unfortunately.
I remember incomprehensible indexing of hideous arrays of characters,
a maddening cascade of unmaintainable if-else statements, and futile,
indescribable attempts to abstract away parts of this unspeakable monstrosity.
If the above paragraph was hard to parse, good! Putting some Lovecraftian
adjectives into a description of events can be a way of coping with terrible
experiences. Those dark, eldritch (sorry, couldn't resist one more) days are
fortunately over. With
parser combinators we
can write composable and fast parsers. Rust adds another adjective here:
safe. nom is a parser combinator library
that works by generating parsing code at compile time with a bunch of macros.
It also tries to avoid allocation and work through input bytes without copying.
I decided to split nom article into two parts.
Today we're focused on parsing text (well, bytes that contain text),
while the next article in the series will cover binary parsing.
This is my first hands-on experience with parser combinators - I'm learning
nom as I write this. Feel free to let me know if the examples here could
be more nom-idiomatic.