Approximately every six months, I approach #zig - a language in its pre-release stage, so there's constantly something new emerging in it.
This time, I wrote `nap` - an "analog" of the `sleep` utility that takes a string in the format 1h15m and then prints the remaining time until the command execution is completed every N seconds.
https://github.com/ninedraft/nap
To implement this, I had to port `time.ParseDuration` from #go - for some reason, I couldn't find an equivalent in the standard Zig library.
I liked several aspects:
- I managed to write the code in a single pass.
- The error messages from the compiler have improved and were helpful throughout the process.
- It turns out there are two community package managers now - https://github.com/nektro/zigmod and https://github.com/mattnite/gyro. Gyro seems to be slightly more mature. However, it doesn't really matter until the language is released.
- The support in vscode has also improved - the Zig LSP works well, although there are some minor things missing, like "run tests by clicking a button above the test code."
durationParse signature
pub fn durationParse(buf: []const u8) DurationParseError!Duration { var d: Duration = 0; var str = buf[0..]; if (str.len == 0) { return DurationParseError.InvalidFormat; } if (eql(u8, str, "0")) { return 0; } while (str.len != 0) { var v: u64 = 0;
Also #TIL: zig has a std.ComptimeStringMap map. It works at compile time and can be used to create global mappings from strings to other values.
const unitMap = ComptimeStringMap(u64, .{ .{ "ns", 1 }, .{ "us", time.ns_per_us }, .{ "µs", time.ns_per_us }, // U+00B5 = micro symbol .{ "μs", time.ns_per_us }, // U+03BC = Greek letter mu .{ "ms", time.ns_per_ms }, .{ "s", time.ns_per_s }, .{ "m", time.ns_per_min }, .{ "h", time.ns_per_hour }, });