Jump: lazy, allocation-free argv parsing in Zig

Hi,

I’m sharing jump, a small Zig library for parsing argv with a very explicit, low-level approach.

It started as a personal project to explore argument parsing but:

  • without upfront schemas
  • without forced structs
  • without allocation
  • without a single-pass “parse everything” model

Instead, jump lets you jump between targeted arguments lazily, using independent cursors that can be copied, rewound, or consumed on demand.

Key Ideas

  • getopt-like syntax, including chained short flags (-abc)
  • lazy parsing: only parse what you ask for
  • no allocation, no rewriting or reordering of argv
  • multiple independent “jumpers”
  • optional upfront validation
  • explicit error handling with contextual debug hints
  • supports subcommands

Scope

jump is intentionally not a framework in which the user evolves, but rather just a set of composable primitives for people who want full control over how and when arguments are interpreted.

The whole library fits in ~350 lines and is heavily covered by tests.
It’s meant for people who like getopt-style control and don’t want a black box.

Peek

There is a demo step!

zig build demo

However, to give an idea right here (errors are printed to stdout as this is a snippet from the demo, which does it on purpose):

var iterator = try std.process.argsWithAllocator(std.heap.page_allocator); // the allocator is never used on POSIX, once on windows...
var myOpt = jump.Over(ArgIterator).init(iterator, 'v', &.{ "verbose", "ver" }, .forbidden, "get useful debug output");

while (myOpt.next()) |opt| {
    // The character returned is a count **per arg** '-v' returns 1 '-vvv' returns 3
    if (opt) |val| try out.print("\t'v' count in same chain: {d}\n", .{val[0]}) else break;
} else |err| {
    switch (err) { // For now there is only one possible error, but switching protects agains future additions...
        jump.LocalParsingError.ForbiddenValue => try out.print("{any}, hint: {s}, {any}\n", .{ err, myOpt.diag.debug_hint }),
        jump.LocalParsingError.MissingValue => unreachable, // the flag was declared with Level.forbidden
    }
}

Repo: GitHub - megaNour/jump: lazy, allocation-free argv parsing in Zig

Feedback welcome!

7 Likes