about summary refs log tree commit diff
path: root/lang/zig/if.zig
diff options
context:
space:
mode:
Diffstat (limited to 'lang/zig/if.zig')
-rw-r--r--lang/zig/if.zig141
1 files changed, 141 insertions, 0 deletions
diff --git a/lang/zig/if.zig b/lang/zig/if.zig
new file mode 100644
index 0000000..99de2b5
--- /dev/null
+++ b/lang/zig/if.zig
@@ -0,0 +1,141 @@
+// If expressions have three uses, corresponding to the three types:
+// * bool
+// * ?T
+// * anyerror!T
+
+const expect = @import("std").testing.expect;
+
+test "if expression" {
+    // If expressions are used instead of a ternary expression.
+    const a: u32 = 5;
+    const b: u32 = 4;
+    const result = if (a != b) 47 else 3089;
+    expect(result == 47);
+}
+
+test "if boolean" {
+    // If expressions test boolean conditions.
+    const a: u32 = 5;
+    const b: u32 = 4;
+    if (a != b) {
+        expect(true);
+    } else if (a == 9) {
+        unreachable;
+    } else {
+        unreachable;
+    }
+}
+
+// If expressions test for null.
+test "if optional" {
+    if (@as(?u32, 0)) |value| {
+        expect(value == 0);
+    } else {
+        unreachable;
+    }
+
+    const b: ?u32 = null;
+    if (b) |value| {
+        unreachable;
+    } else {
+        expect(true);
+    }
+    // To test against null only, use the binary equality operator.
+    if (b == null)
+        expect(true);
+
+    // Access the value by reference using a pointer capture.
+    var c: ?u32 = 3;
+    if (c) |*value|
+        value.* = 2;
+    // The else is not required.
+    if (c) |value|
+        expect(value == 2);
+}
+
+// If expressions test for errors.  Note the |err| capture on the else.
+test "if error union" {
+    const a: anyerror!u32 = 0;
+    if (a) |value| {
+        expect(value == 0);
+    } else |err| {
+        unreachable;
+    }
+
+    const b: anyerror!u32 = error.BadValue;
+    if (b) |value| {
+        unreachable;
+    } else |err| {
+        expect(err == error.BadValue);
+    }
+
+    // The else and |err| capture is strictly required.
+    if (a) |value| {
+        expect(value == 0);
+    } else |_| {}
+
+    // To check only the error value, use an empty block expression.
+    if (b) |_| {} else |err| {
+        expect(err == error.BadValue);
+    }
+
+    // Access the value by reference using a pointer capture.
+    var c: anyerror!u32 = 3;
+    if (c) |*value| {
+        value.* = 9;
+    } else |err| {
+        unreachable;
+    }
+
+    if (c) |value| {
+        expect(value == 9);
+    } else |err| {
+        unreachable;
+    }
+}
+
+// If expressions test for errors before unwrapping optionals.
+// The |optional_value| capture's type is ?u32.
+test "if error union with optional" {
+    const a: anyerror!?u32 = 0;
+    if (a) |optional_value| {
+        expect(optional_value.? == 0);
+    } else |err| {
+        unreachable;
+    }
+
+    const b: anyerror!?u32 = null;
+    if (b) |optional_value| {
+        expect(optional_value == null);
+    } else |err| {
+        unreachable;
+    }
+    if (b) |*optional_value| {
+        if (optional_value.*) |_|
+            unreachable;
+    } else |err| {
+        unreachable;
+    }
+
+    const c: anyerror!?u32 = error.BadValue;
+    if (c) |optional_value| {
+        unreachable;
+    } else |err| {
+        expect(err == error.BadValue);
+    }
+
+    // Access the value by reference by using a pointer capture each time.
+    var d: anyerror!?u32 = 3;
+    if (d) |*optional_value| {
+        if (optional_value.*) |*value| {
+            value.* = 9;
+        }
+    } else |err| {
+        unreachable;
+    }
+    if (d) |optional_value| {
+        expect(optional_value.? == 9);
+    } else |err| {
+        unreachable;
+    }
+}