authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-09-21 17:23:51 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-09-21 17:23:51 -07:00
log9f2ec2b07f59d5ed208f66c880bc8b3909bf1049
tree7245cabc3a850d776ed4e5f0a1900b68b0c248af
parentb5915131ce5b41e58a901973b518f9769215e754

add isZigString


2 files changed, 147 insertions(+), 0 deletions(-)

src/isZigString.zig created+146
...@@ -0,0 +1,146 @@
1const std = @import("std");
2const string = []const u8;
3const extras = @import("./lib.zig");
4
5/// Returns true if the passed type will coerce to []const u8.
6/// Any of the following are considered strings:
7/// ```
8/// []const u8, [:S]const u8, *const [N]u8, *const [N:S]u8,
9/// []u8, [:S]u8, *[:S]u8, *[N:S]u8.
10/// ```
11/// These types are not considered strings:
12/// ```
13/// u8, [N]u8, [*]const u8, [*:0]const u8,
14/// [*]const [N]u8, []const u16, []const i8,
15/// *const u8, ?[]const u8, ?*const [N]u8.
16/// ```
17pub fn isZigString(comptime T: type) bool {
18 return comptime blk: {
19 // Only pointer types can be strings, no optionals
20 const info = @typeInfo(T);
21 if (info != .Pointer) break :blk false;
22
23 const ptr = &info.Pointer;
24 // Check for CV qualifiers that would prevent coerction to []const u8
25 if (ptr.is_volatile or ptr.is_allowzero) break :blk false;
26
27 // If it's already a slice, simple check.
28 if (ptr.size == .Slice) {
29 break :blk ptr.child == u8;
30 }
31
32 // Otherwise check if it's an array type that coerces to slice.
33 if (ptr.size == .One) {
34 const child = @typeInfo(ptr.child);
35 if (child == .Array) {
36 const arr = &child.Array;
37 break :blk arr.child == u8;
38 }
39 }
40
41 break :blk false;
42 };
43}
44
45test {
46 try std.testing.expect(isZigString([]const u8));
47}
48test {
49 try std.testing.expect(isZigString([]u8));
50}
51test {
52 try std.testing.expect(isZigString([:0]const u8));
53}
54test {
55 try std.testing.expect(isZigString([:0]u8));
56}
57test {
58 try std.testing.expect(isZigString([:5]const u8));
59}
60test {
61 try std.testing.expect(isZigString([:5]u8));
62}
63test {
64 try std.testing.expect(isZigString(*const [0]u8));
65}
66test {
67 try std.testing.expect(isZigString(*[0]u8));
68}
69test {
70 try std.testing.expect(isZigString(*const [0:0]u8));
71}
72test {
73 try std.testing.expect(isZigString(*[0:0]u8));
74}
75test {
76 try std.testing.expect(isZigString(*const [0:5]u8));
77}
78test {
79 try std.testing.expect(isZigString(*[0:5]u8));
80}
81test {
82 try std.testing.expect(isZigString(*const [10]u8));
83}
84test {
85 try std.testing.expect(isZigString(*[10]u8));
86}
87test {
88 try std.testing.expect(isZigString(*const [10:0]u8));
89}
90test {
91 try std.testing.expect(isZigString(*[10:0]u8));
92}
93test {
94 try std.testing.expect(isZigString(*const [10:5]u8));
95}
96test {
97 try std.testing.expect(isZigString(*[10:5]u8));
98}
99test {
100 try std.testing.expect(!isZigString(u8));
101}
102test {
103 try std.testing.expect(!isZigString([4]u8));
104}
105test {
106 try std.testing.expect(!isZigString([4:0]u8));
107}
108test {
109 try std.testing.expect(!isZigString([*]const u8));
110}
111test {
112 try std.testing.expect(!isZigString([*]const [4]u8));
113}
114test {
115 try std.testing.expect(!isZigString([*c]const u8));
116}
117test {
118 try std.testing.expect(!isZigString([*c]const [4]u8));
119}
120test {
121 try std.testing.expect(!isZigString([*:0]const u8));
122}
123test {
124 try std.testing.expect(!isZigString([*:0]const u8));
125}
126test {
127 try std.testing.expect(!isZigString(*[]const u8));
128}
129test {
130 try std.testing.expect(!isZigString(?[]const u8));
131}
132test {
133 try std.testing.expect(!isZigString(?*const [4]u8));
134}
135test {
136 try std.testing.expect(!isZigString([]allowzero u8));
137}
138test {
139 try std.testing.expect(!isZigString([]volatile u8));
140}
141test {
142 try std.testing.expect(!isZigString(*allowzero [4]u8));
143}
144test {
145 try std.testing.expect(!isZigString(*volatile [4]u8));
146}
src/lib.zig+1
...@@ -95,3 +95,4 @@ pub usingnamespace @import("./rawIntBytes.zig");...@@ -95,3 +95,4 @@ pub usingnamespace @import("./rawIntBytes.zig");
95pub usingnamespace @import("./globalOption.zig");95pub usingnamespace @import("./globalOption.zig");
96pub usingnamespace @import("./OneSmallerInt.zig");96pub usingnamespace @import("./OneSmallerInt.zig");
97pub usingnamespace @import("./FlippedInt.zig");97pub usingnamespace @import("./FlippedInt.zig");
98pub usingnamespace @import("./isZigString.zig");