I think the first step is to simplify the boolean logic, rewritten this becomes:
fn is_ok(v: anytype) bool {
_ = v catch return false;
return true;
}
pub fn check_install_name(name: []const u8) bool {
...
var components = std.mem.split(u8, name[4..], "-");
...
const version = components.next() catch return false;
return streql(v, "stable") or streql(v, "master") or is_ok(std.SemanticVersion.parse(v));
}
Don’t use if to branch just to return true or false again.
I don’t think a function like is_ok needs to be part of the standard library, usually I would just bubble the error up when there is an error and then actually do something with the error, instead of converting it to a true or false. It is better to handle the error somewhere then to convert it to a boolean, possibly forgetting to handle it.
I think it is so simple that there is no point in making it part of a library and not the usual way to handle errors in Zig.
Is ok seems to be a Rust pattern, I think using try and handling errors directly is more Zig idiomatic.
I might even change the code towards something like this:
pub fn check_install_name(name: []const u8) !void {
var components = std.mem.split(u8, name[4..], "-");
const version = try components.next();
const v = ...;
if(streql(v, "stable") or streql(v, "master")) return;
_ = try std.SemanticVersion.parse(v);
}
So check is just void on success and if there is an error it gets handled somewhere, whether you recover from it, or catch it and print and abort with it, is decision of the caller.
Why use booleans to effect control flow if you already have error values that can do that directly and with support for multiple different ways to handle those errors?
There can be situations where it makes sense, to drop errors or convert them to different errors, for example in this case it might make sense to convert some detailed error into some more general error.UnknownVersion
or something like that.
Wait a minute, I haven’t really used std.mem.split
but it returns a normal iterator, so next
returns an optional not an error!
const version = components.next() orelse return error.UnknownVersion;