diff --git a/src/switching_on_strings.zig b/src/switching_on_strings.zig new file mode 100644 index 0000000..072e419 --- /dev/null +++ b/src/switching_on_strings.zig @@ -0,0 +1,38 @@ +const std = @import("std"); + +// Switching on strings isn't allowed in zig, because all switch statement +// end up turning into a [jump table](https://en.wikipedia.org/wiki/Branch_table) +// but you can't do that with a string. + +// To start with you create an enum with the value of each item that you want +// to support. Here I am using 4 values with numbers. +const Number = enum { + One, + Two, + Three, + Four, + + // Then we add a parse function, which allos the Number to be parsed into + // a Number via a StaticStringMap. The map itself is created at comptime, + // so is effectively hardcoded into the function + fn parse(s: []const u8) ?Number { + const map = std.StaticStringMap(Number).initComptime(.{ + .{ "one", .One }, + .{ "two", .Two }, + .{ "three", .Three }, + .{ "four", .Four }, + }); + return map.get(s); + } +}; + +test "Switch StaticStringMap" { + // Now when we actually do the switch, we parse it into an enum, and then + // can do an exhaustive switch on that. Since we could be passed something + // that doesn't exist, we have to also support null. + std.testing.expectEqual(switch (Number.parse("two")) { + null => "", + .One, .Two => "fizz", + .Three, .Four => "buzz", + }, "fizz"); +}