Expression on left-hand side of `orelse` statement

Somewhat new to the language here, so this might be a dumb question, but I’m kinda struggling to find a nice readable way of doing this…

I have some code here that formats 2 comptime ?usize values (min and max) into a string…

const expectedRange =
    fmt.comptimePrint("{}...{}", .{ min orelse "", max orelse "" });

For example, I want this to print 1... if min and max are 1 and null.

The issue is that min orelse "" is either a usize OR a []const u8 if min is null… (I think?)
I tried using {?} as the format specifier and taking out the orelse "" parts, but that prints null instead of nothing, and I can’t customize the output for nulls as far as I can tell…

If I leave the brackets empty, it complains that I can’t format an array reference without specifiers, but if I do, {s} it complains since the possible usize values aren’t strings. What’s the best way of doing this?

This code here is what I have so far, and does what I want, but there’s gotta be a better way of doing this… :sob:

// display-formatted expected range
const expectedRange = makeRangeStr: {
    const minD = if (min != null) fmt.comptimePrint("{?}", .{min}) else "";
    const maxD = if (max != null) fmt.comptimePrint("{?}", .{max}) else "";

    break :makeRangeStr fmt.comptimePrint("{s}...{s}", .{ minD, maxD });
};

Thanks.

1 Like

Format-strings eh, @Dexie?

The keyword “orelse” is very useful for early returns… for instance:

const ptr = malloc(1234) orelse return null; // forwards the null

As I think you pointed out, there’s a mix-up between type categories for a single statement (int vs string).

You can always compose them together if you find it more pleasant:

    const x: ?usize = null;
    const y: ?usize = 10;

    const result = std.fmt.comptimePrint("{s}...{s}", .{
        if (x) |i| std.fmt.comptimePrint("{}", .{i}) else "",
        if (y) |i| std.fmt.comptimePrint("{}", .{i}) else ""
    });

    std.debug.print("\n{s}\n", .{result});

Anyhow, welcome to the forum!

4 Likes