Simple straightforward library for CLI arg parsing (or rather lexing)

Hey,

after started coding in Zig last.week, I already like the language very much. Thus, I was looking for a first project to learn the basic language features.

In Rust I always use the lexopt crate for parsing CLI args since its simple and in contrast to more sophisticated but complex approaches like clap gives most control to me, the user.

While there are already many CLI parsing libs in Zig, I couldn’t find one which fits my specific needs like lexopt does for Rust. Thus, I decided to try to port lexopt to Zig as a learning project which also covers a need.

Here is the result:

https://codeberg.org/lukeflo/lexopts

Since this is my first try in Zig, I bet the code has many inefficient and non-idiomatic parts that can be improved. Thus, if you find some or have other tipps, I’m happy for your feedback (as comment here or as issue at the repo which might be better for explicit code parts).

8 Likes

Thanks to some contributions by @TemariVirus (might not have a Ziggit account) lexopts now has received some small enhancements/upgrades.

Furthermore the arg matching loop is now simpler with less nested functions. And, of course, stable 0.16.0 is fully supported (not that there were some major issues…).

Follwoing the discussion a disclaimer: Not a single char written or even suggested by any LLM :slightly_smiling_face:

1 Like

I’m not so sure. I’m not advanced enough to offer valuable critique on my perusal, but I see a lot of great things:

  • lots of tests, testing a nice variety, and offering plenty of “example code” (“dual duty test code”)
  • there isn’t a lot of opportunity for inefficiency here - do I spy even a single loop? I guess there’s the args iterator (though the use of the switch there is a less familiar and maybe-forced pattern that might have a plainer flavor). But otherwise your switches look pretty idiomatic to me. You have a nice tagged-union states and options.
  • I’m wondering if the unreachablesare truly the best option (truly “impossible”, as far as you can see, with the current code), as opposed to errors. If they are, perhaps else => unreachable is the indicator that the only possibilities ever expected are the prongs you provide. (I guess you use one to document the unique way pending_value is treated….)

Everything is nice and clean; doc comments are clear and plentiful, though sometimes maybe at odds with the code? (Parser.init()comment suggests “Asserts that args has at least one element.“, but I don’t see the obvious assertion…?)

Anyway, nice work; easy read. Hopefully it’s working well for you? I intend to do some more work that requires cli, soon, and I’ll have to evaluate the offerings… I’m not even sure about my eval criteria yet, except that I’ll want simple rather than infinitely-configurable/abstract.

1 Like

Thanks for the detailed feedback. Of course, its a rather simple project, but I like the low level approach and it works great in all of my private little helper tools.

1 Like

At first glance this looks very sane. I think I’ll give this a go at some point.

A complete “code golf” aspect you could explore is how much can be baked in at comptime. Your options are going to be defined at comptime, so what you search for can be constant. Of course… it’s not necessary at all for an argument parser library. They run once at the start of a program and are never a performance issue. However if you wanted to explore that part of the language, you could.

1 Like