@@ -43,12 +43,15 @@ pub fn ComptimeStringMapWithEql(
43
43
comptime kvs_list : anytype ,
44
44
comptime eql : fn (a : []const u8 , b : []const u8 ) bool ,
45
45
) type {
46
- const precomputed = comptime blk : {
46
+ const empty_list = kvs_list .len == 0 ;
47
+ const precomputed = blk : {
47
48
@setEvalBranchQuota (1500 );
48
49
const KV = struct {
49
50
key : []const u8 ,
50
51
value : V ,
51
52
};
53
+ if (empty_list )
54
+ break :blk .{};
52
55
var sorted_kvs : [kvs_list .len ]KV = undefined ;
53
56
for (kvs_list , 0.. ) | kv , i | {
54
57
if (V != void ) {
@@ -103,10 +106,16 @@ pub fn ComptimeStringMapWithEql(
103
106
104
107
/// Returns the value for the key if any, else null.
105
108
pub fn get (str : []const u8 ) ? V {
109
+ if (empty_list )
110
+ return null ;
111
+
106
112
return precomputed .sorted_kvs [getIndex (str ) orelse return null ].value ;
107
113
}
108
114
109
115
pub fn getIndex (str : []const u8 ) ? usize {
116
+ if (empty_list )
117
+ return null ;
118
+
110
119
if (str .len < precomputed .min_len or str .len > precomputed .max_len )
111
120
return null ;
112
121
@@ -143,6 +152,9 @@ test "ComptimeStringMap list literal of list literals" {
143
152
});
144
153
145
154
try testMap (map );
155
+
156
+ // Default comparison is case sensitive
157
+ try std .testing .expect (null == map .get ("NOTHING" ));
146
158
}
147
159
148
160
test "ComptimeStringMap array of structs" {
@@ -181,6 +193,9 @@ fn testMap(comptime map: anytype) !void {
181
193
182
194
try std .testing .expect (! map .has ("missing" ));
183
195
try std .testing .expect (map .has ("these" ));
196
+
197
+ try std .testing .expect (null == map .get ("" ));
198
+ try std .testing .expect (null == map .get ("averylongstringthathasnomatches" ));
184
199
}
185
200
186
201
test "ComptimeStringMap void value type, slice of structs" {
@@ -195,6 +210,9 @@ test "ComptimeStringMap void value type, slice of structs" {
195
210
const map = ComptimeStringMap (void , slice );
196
211
197
212
try testSet (map );
213
+
214
+ // Default comparison is case sensitive
215
+ try std .testing .expect (null == map .get ("NOTHING" ));
198
216
}
199
217
200
218
test "ComptimeStringMap void value type, list literal of list literals" {
@@ -218,6 +236,9 @@ fn testSet(comptime map: anytype) !void {
218
236
219
237
try std .testing .expect (! map .has ("missing" ));
220
238
try std .testing .expect (map .has ("these" ));
239
+
240
+ try std .testing .expect (null == map .get ("" ));
241
+ try std .testing .expect (null == map .get ("averylongstringthathasnomatches" ));
221
242
}
222
243
223
244
test "ComptimeStringMapWithEql" {
@@ -236,3 +257,45 @@ test "ComptimeStringMapWithEql" {
236
257
237
258
try std .testing .expect (map .has ("ThESe" ));
238
259
}
260
+
261
+ test "ComptimeStringMap empty" {
262
+ const m1 = ComptimeStringMap (usize , .{});
263
+ try std .testing .expect (null == m1 .get ("anything" ));
264
+
265
+ const m2 = ComptimeStringMapWithEql (usize , .{}, eqlAsciiIgnoreCase );
266
+ try std .testing .expect (null == m2 .get ("anything" ));
267
+ }
268
+
269
+ test "ComptimeStringMap redundant entries" {
270
+ const map = ComptimeStringMap (TestEnum , .{
271
+ .{ "redundant" , .D },
272
+ .{ "theNeedle" , .A },
273
+ .{ "redundant" , .B },
274
+ .{ "re" ++ "dundant" , .C },
275
+ .{ "redun" ++ "dant" , .E },
276
+ });
277
+
278
+ // No promises about which one you get:
279
+ try std .testing .expect (null != map .get ("redundant" ));
280
+
281
+ // Default map is not case sensitive:
282
+ try std .testing .expect (null == map .get ("REDUNDANT" ));
283
+
284
+ try std .testing .expectEqual (TestEnum .A , map .get ("theNeedle" ).? );
285
+ }
286
+
287
+ test "ComptimeStringMap redundant insensitive" {
288
+ const map = ComptimeStringMapWithEql (TestEnum , .{
289
+ .{ "redundant" , .D },
290
+ .{ "theNeedle" , .A },
291
+ .{ "redundanT" , .B },
292
+ .{ "RE" ++ "dundant" , .C },
293
+ .{ "redun" ++ "DANT" , .E },
294
+ }, eqlAsciiIgnoreCase );
295
+
296
+ // No promises about which result you'll get ...
297
+ try std .testing .expect (null != map .get ("REDUNDANT" ));
298
+ try std .testing .expect (null != map .get ("ReDuNdAnT" ));
299
+
300
+ try std .testing .expectEqual (TestEnum .A , map .get ("theNeedle" ).? );
301
+ }
0 commit comments