From 9f2ec2b07f59d5ed208f66c880bc8b3909bf1049 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Sat, 21 Sep 2024 17:23:51 -0700 Subject: [PATCH] add isZigString --- src/isZigString.zig | 146 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.zig | 1 + 2 files changed, 147 insertions(+) create mode 100644 src/isZigString.zig diff --git a/src/isZigString.zig b/src/isZigString.zig new file mode 100644 index 0000000000000000000000000000000000000000..08986ffed432465265ddbad706b09522cc36ce6e --- /dev/null +++ b/src/isZigString.zig @@ -0,0 +1,146 @@ +const std = @import("std"); +const string = []const u8; +const extras = @import("./lib.zig"); + +/// Returns true if the passed type will coerce to []const u8. +/// Any of the following are considered strings: +/// ``` +/// []const u8, [:S]const u8, *const [N]u8, *const [N:S]u8, +/// []u8, [:S]u8, *[:S]u8, *[N:S]u8. +/// ``` +/// These types are not considered strings: +/// ``` +/// u8, [N]u8, [*]const u8, [*:0]const u8, +/// [*]const [N]u8, []const u16, []const i8, +/// *const u8, ?[]const u8, ?*const [N]u8. +/// ``` +pub fn isZigString(comptime T: type) bool { + return comptime blk: { + // Only pointer types can be strings, no optionals + const info = @typeInfo(T); + if (info != .Pointer) break :blk false; + + const ptr = &info.Pointer; + // Check for CV qualifiers that would prevent coerction to []const u8 + if (ptr.is_volatile or ptr.is_allowzero) break :blk false; + + // If it's already a slice, simple check. + if (ptr.size == .Slice) { + break :blk ptr.child == u8; + } + + // Otherwise check if it's an array type that coerces to slice. + if (ptr.size == .One) { + const child = @typeInfo(ptr.child); + if (child == .Array) { + const arr = &child.Array; + break :blk arr.child == u8; + } + } + + break :blk false; + }; +} + +test { + try std.testing.expect(isZigString([]const u8)); +} +test { + try std.testing.expect(isZigString([]u8)); +} +test { + try std.testing.expect(isZigString([:0]const u8)); +} +test { + try std.testing.expect(isZigString([:0]u8)); +} +test { + try std.testing.expect(isZigString([:5]const u8)); +} +test { + try std.testing.expect(isZigString([:5]u8)); +} +test { + try std.testing.expect(isZigString(*const [0]u8)); +} +test { + try std.testing.expect(isZigString(*[0]u8)); +} +test { + try std.testing.expect(isZigString(*const [0:0]u8)); +} +test { + try std.testing.expect(isZigString(*[0:0]u8)); +} +test { + try std.testing.expect(isZigString(*const [0:5]u8)); +} +test { + try std.testing.expect(isZigString(*[0:5]u8)); +} +test { + try std.testing.expect(isZigString(*const [10]u8)); +} +test { + try std.testing.expect(isZigString(*[10]u8)); +} +test { + try std.testing.expect(isZigString(*const [10:0]u8)); +} +test { + try std.testing.expect(isZigString(*[10:0]u8)); +} +test { + try std.testing.expect(isZigString(*const [10:5]u8)); +} +test { + try std.testing.expect(isZigString(*[10:5]u8)); +} +test { + try std.testing.expect(!isZigString(u8)); +} +test { + try std.testing.expect(!isZigString([4]u8)); +} +test { + try std.testing.expect(!isZigString([4:0]u8)); +} +test { + try std.testing.expect(!isZigString([*]const u8)); +} +test { + try std.testing.expect(!isZigString([*]const [4]u8)); +} +test { + try std.testing.expect(!isZigString([*c]const u8)); +} +test { + try std.testing.expect(!isZigString([*c]const [4]u8)); +} +test { + try std.testing.expect(!isZigString([*:0]const u8)); +} +test { + try std.testing.expect(!isZigString([*:0]const u8)); +} +test { + try std.testing.expect(!isZigString(*[]const u8)); +} +test { + try std.testing.expect(!isZigString(?[]const u8)); +} +test { + try std.testing.expect(!isZigString(?*const [4]u8)); +} +test { + try std.testing.expect(!isZigString([]allowzero u8)); +} +test { + try std.testing.expect(!isZigString([]volatile u8)); +} +test { + try std.testing.expect(!isZigString(*allowzero [4]u8)); +} +test { + try std.testing.expect(!isZigString(*volatile [4]u8)); +} diff --git a/src/lib.zig b/src/lib.zig index 959008e8545b49c7029cad304801d44ead4e62fb..e0f05139f7b97b1cb897b7561cb09883ebe28d8d 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -95,3 +95,4 @@ pub usingnamespace @import("./rawIntBytes.zig"); pub usingnamespace @import("./globalOption.zig"); pub usingnamespace @import("./OneSmallerInt.zig"); pub usingnamespace @import("./FlippedInt.zig"); +pub usingnamespace @import("./isZigString.zig"); -- 2.54.0