aboutsummaryrefslogtreecommitdiff
path: root/examples/hello-zig/src/root.zig
blob: f6600ac87773b98624cbc5f4368058abe3f4244e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const std = @import("std");

pub const OutputStyle = enum {
    compact,
    verbose,
};

pub const NumberKind = union(enum) {
    negative: i64,
    zero,
    positive: u64,
};

pub const Greeter = struct {
    name: []const u8,
    punctuation: u8 = '!',

    pub fn write(self: Greeter, writer: anytype, style: OutputStyle) !void {
        switch (style) {
            .compact => try writer.print("hello, {s}{c}\n", .{ self.name, self.punctuation }),
            .verbose => {
                try writer.print(
                    \\hello, {s}{c}
                    \\this sample is here to exercise Zig syntax support in Nova.
                    \\
                , .{ self.name, self.punctuation });
            },
        }
    }
};

pub fn classifyNumber(value: i64) NumberKind {
    if (value == 0) return .zero;
    if (value < 0) return .{ .negative = value };
    return .{ .positive = @intCast(value) };
}

pub fn describeNumber(allocator: std.mem.Allocator, value: i64) ![]u8 {
    return switch (classifyNumber(value)) {
        .zero => std.fmt.allocPrint(allocator, "zero", .{}),
        .negative => |negative| std.fmt.allocPrint(allocator, "negative({d})", .{negative}),
        .positive => |positive| std.fmt.allocPrint(allocator, "positive({d})", .{positive}),
    };
}

pub fn collectEvenSquares(
    allocator: std.mem.Allocator,
    values: []const i32,
) !std.ArrayList(i32) {
    var result: std.ArrayList(i32) = .empty;
    errdefer result.deinit(allocator);

    for (values) |value| {
        if (@mod(value, 2) != 0) continue;
        try result.append(allocator, value * value);
    }

    return result;
}

test "classifyNumber covers the main branches" {
    try std.testing.expectEqual(NumberKind{ .negative = -5 }, classifyNumber(-5));
    try std.testing.expectEqual(NumberKind.zero, classifyNumber(0));
    try std.testing.expectEqual(NumberKind{ .positive = 9 }, classifyNumber(9));
}

test "collectEvenSquares keeps only even numbers" {
    const values = [_]i32{ -4, -3, 0, 1, 2, 7 };
    var result = try collectEvenSquares(std.testing.allocator, &values);
    defer result.deinit(std.testing.allocator);

    try std.testing.expectEqualSlices(i32, &.{ 16, 0, 4 }, result.items);
}

test "Greeter.write renders verbose output" {
    var list: std.ArrayList(u8) = .empty;
    defer list.deinit(std.testing.allocator);

    const writer = list.writer(std.testing.allocator);
    try (Greeter{ .name = "Zig" }).write(writer, .verbose);

    try std.testing.expect(std.mem.indexOf(u8, list.items, "exercise Zig syntax support") != null);
}